summaryrefslogtreecommitdiff
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/connected.c6
-rw-r--r--zebra/connected.h7
-rw-r--r--zebra/debug.c28
-rw-r--r--zebra/debug.h15
-rw-r--r--zebra/if_netlink.h8
-rw-r--r--zebra/interface.h8
-rw-r--r--zebra/ioctl.h8
-rw-r--r--zebra/ioctl_solaris.h8
-rw-r--r--zebra/ipforward.h8
-rw-r--r--zebra/irdp.h7
-rw-r--r--zebra/irdp_main.c2
-rw-r--r--zebra/irdp_packet.c4
-rw-r--r--zebra/kernel_netlink.c48
-rw-r--r--zebra/kernel_netlink.h8
-rw-r--r--zebra/kernel_socket.c4
-rw-r--r--zebra/kernel_socket.h8
-rw-r--r--zebra/label_manager.h8
-rw-r--r--zebra/main.c2
-rw-r--r--zebra/redistribute.h9
-rw-r--r--zebra/rib.h27
-rw-r--r--zebra/router-id.h8
-rw-r--r--zebra/rt.h11
-rw-r--r--zebra/rt_netlink.c11
-rw-r--r--zebra/rt_netlink.h8
-rw-r--r--zebra/rt_socket.c54
-rw-r--r--zebra/rtadv.h7
-rw-r--r--zebra/rule_netlink.h8
-rw-r--r--zebra/table_manager.h8
-rw-r--r--zebra/zapi_msg.c16
-rw-r--r--zebra/zapi_msg.h8
-rw-r--r--zebra/zebra_dplane.h8
-rw-r--r--zebra/zebra_errors.h8
-rw-r--r--zebra/zebra_fpm_private.h9
-rw-r--r--zebra/zebra_l2.h9
-rw-r--r--zebra/zebra_memory.h8
-rw-r--r--zebra/zebra_mlag.h9
-rw-r--r--zebra/zebra_mpls.h40
-rw-r--r--zebra/zebra_mroute.h8
-rw-r--r--zebra/zebra_netns_id.h8
-rw-r--r--zebra/zebra_netns_notify.h8
-rw-r--r--zebra/zebra_ns.h8
-rw-r--r--zebra/zebra_pbr.h8
-rw-r--r--zebra/zebra_ptm.c4
-rw-r--r--zebra/zebra_ptm.h9
-rw-r--r--zebra/zebra_ptm_redistribute.h10
-rw-r--r--zebra/zebra_pw.h8
-rw-r--r--zebra/zebra_rib.c354
-rw-r--r--zebra/zebra_rnh.c200
-rw-r--r--zebra/zebra_rnh.h19
-rw-r--r--zebra/zebra_routemap.h8
-rw-r--r--zebra/zebra_router.c2
-rw-r--r--zebra/zebra_router.h24
-rw-r--r--zebra/zebra_vrf.c32
-rw-r--r--zebra/zebra_vrf.h15
-rw-r--r--zebra/zebra_vty.c50
-rw-r--r--zebra/zebra_vxlan.c109
-rw-r--r--zebra/zebra_vxlan.h15
-rw-r--r--zebra/zebra_vxlan_private.h10
-rw-r--r--zebra/zserv.c12
-rw-r--r--zebra/zserv.h15
60 files changed, 1060 insertions, 329 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index 128f397552..7114a3286b 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -272,7 +272,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)
ifp->vrf_id, ifp->name,
prefix2str(&p, buf, sizeof(buf)));
}
- mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id));
+ mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), &p);
}
}
@@ -437,7 +437,7 @@ void connected_down(struct interface *ifp, struct connected *ifc)
ifp->vrf_id, ifp->name,
prefix2str(&p, buf, sizeof(buf)));
}
- mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id));
+ mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), &p);
}
}
@@ -471,7 +471,7 @@ static void connected_delete_helper(struct connected *ifc, struct prefix *p)
ifp->vrf_id, ifp->name,
prefix2str(p, buf, sizeof(buf)));
}
- mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id));
+ mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), p);
}
}
diff --git a/zebra/connected.h b/zebra/connected.h
index faba30b0d5..7672bec006 100644
--- a/zebra/connected.h
+++ b/zebra/connected.h
@@ -28,6 +28,10 @@
#include "lib/if.h"
#include "lib/prefix.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern struct connected *connected_check(struct interface *ifp,
union prefixconstptr p);
extern struct connected *connected_check_ptp(struct interface *ifp,
@@ -58,4 +62,7 @@ extern void connected_delete_ipv6(struct interface *ifp,
extern int connected_is_unnumbered(struct interface *);
+#ifdef __cplusplus
+}
+#endif
#endif /*_ZEBRA_CONNECTED_H */
diff --git a/zebra/debug.c b/zebra/debug.c
index 87999a1bbc..8e5fb0ea10 100644
--- a/zebra/debug.c
+++ b/zebra/debug.c
@@ -87,7 +87,9 @@ DEFUN_NOSH (show_debugging_zebra,
if (IS_ZEBRA_DEBUG_FPM)
vty_out(vty, " Zebra FPM debugging is on\n");
- if (IS_ZEBRA_DEBUG_NHT)
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+ vty_out(vty, " Zebra detailed next-hop tracking debugging is on\n");
+ else if (IS_ZEBRA_DEBUG_NHT)
vty_out(vty, " Zebra next-hop tracking debugging is on\n");
if (IS_ZEBRA_DEBUG_MPLS)
vty_out(vty, " Zebra MPLS debugging is on\n");
@@ -119,12 +121,19 @@ DEFUN (debug_zebra_events,
DEFUN (debug_zebra_nht,
debug_zebra_nht_cmd,
- "debug zebra nht",
+ "debug zebra nht [detailed]",
DEBUG_STR
"Zebra configuration\n"
- "Debug option set for zebra next hop tracking\n")
+ "Debug option set for zebra next hop tracking\n"
+ "Debug option set for detailed info\n")
{
+ int idx = 0;
+
zebra_debug_nht = ZEBRA_DEBUG_NHT;
+
+ if (argv_find(argv, argc, "detailed", &idx))
+ zebra_debug_nht |= ZEBRA_DEBUG_NHT_DETAILED;
+
return CMD_SUCCESS;
}
@@ -320,11 +329,12 @@ DEFUN (no_debug_zebra_events,
DEFUN (no_debug_zebra_nht,
no_debug_zebra_nht_cmd,
- "no debug zebra nht",
+ "no debug zebra nht [detailed]",
NO_STR
DEBUG_STR
"Zebra configuration\n"
- "Debug option set for zebra next hop tracking\n")
+ "Debug option set for zebra next hop tracking\n"
+ "Debug option set for detailed info\n")
{
zebra_debug_nht = 0;
return CMD_SUCCESS;
@@ -490,10 +500,15 @@ static int config_write_debug(struct vty *vty)
vty_out(vty, "debug zebra fpm\n");
write++;
}
- if (IS_ZEBRA_DEBUG_NHT) {
+
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+ vty_out(vty, "debug zebra nht detailed\n");
+ write++;
+ } else if (IS_ZEBRA_DEBUG_NHT) {
vty_out(vty, "debug zebra nht\n");
write++;
}
+
if (IS_ZEBRA_DEBUG_MPLS) {
vty_out(vty, "debug zebra mpls\n");
write++;
@@ -530,6 +545,7 @@ void zebra_debug_init(void)
zebra_debug_pw = 0;
zebra_debug_dplane = 0;
zebra_debug_mlag = 0;
+ zebra_debug_nht = 0;
install_node(&debug_node, config_write_debug);
diff --git a/zebra/debug.h b/zebra/debug.h
index c79cd96c21..176226f7ae 100644
--- a/zebra/debug.h
+++ b/zebra/debug.h
@@ -24,6 +24,10 @@
#include "lib/vty.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Debug flags. */
#define ZEBRA_DEBUG_EVENT 0x01
@@ -40,7 +44,9 @@
#define ZEBRA_DEBUG_RIB_DETAILED 0x02
#define ZEBRA_DEBUG_FPM 0x01
-#define ZEBRA_DEBUG_NHT 0x01
+
+#define ZEBRA_DEBUG_NHT 0x01
+#define ZEBRA_DEBUG_NHT_DETAILED 0x02
#define ZEBRA_DEBUG_MPLS 0x01
@@ -72,7 +78,10 @@
#define IS_ZEBRA_DEBUG_RIB_DETAILED (zebra_debug_rib & ZEBRA_DEBUG_RIB_DETAILED)
#define IS_ZEBRA_DEBUG_FPM (zebra_debug_fpm & ZEBRA_DEBUG_FPM)
+
#define IS_ZEBRA_DEBUG_NHT (zebra_debug_nht & ZEBRA_DEBUG_NHT)
+#define IS_ZEBRA_DEBUG_NHT_DETAILED (zebra_debug_nht & ZEBRA_DEBUG_NHT_DETAILED)
+
#define IS_ZEBRA_DEBUG_MPLS (zebra_debug_mpls & ZEBRA_DEBUG_MPLS)
#define IS_ZEBRA_DEBUG_VXLAN (zebra_debug_vxlan & ZEBRA_DEBUG_VXLAN)
#define IS_ZEBRA_DEBUG_PW (zebra_debug_pw & ZEBRA_DEBUG_PW)
@@ -99,4 +108,8 @@ extern void zebra_debug_init(void);
DECLARE_HOOK(zebra_debug_show_debugging, (struct vty *vty), (vty));
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_DEBUG_H */
diff --git a/zebra/if_netlink.h b/zebra/if_netlink.h
index 65a266a519..710fd52558 100644
--- a/zebra/if_netlink.h
+++ b/zebra/if_netlink.h
@@ -23,11 +23,19 @@
#ifdef HAVE_NETLINK
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id,
int startup);
extern int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup);
extern int interface_lookup_netlink(struct zebra_ns *zns);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* HAVE_NETLINK */
#endif /* _ZEBRA_IF_NETLINK_H */
diff --git a/zebra/interface.h b/zebra/interface.h
index 1dbcf33fad..ce404e8253 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -28,6 +28,10 @@
#include "zebra/zebra_l2.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* For interface multicast configuration. */
#define IF_ZEBRA_MULTICAST_UNSPEC 0
#define IF_ZEBRA_MULTICAST_ON 1
@@ -432,4 +436,8 @@ extern int interface_list_proc(void);
extern int ifaddr_proc_ipv6(void);
#endif /* HAVE_PROC_NET_IF_INET6 */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_INTERFACE_H */
diff --git a/zebra/ioctl.h b/zebra/ioctl.h
index 2a8ea77909..67ffd45a08 100644
--- a/zebra/ioctl.h
+++ b/zebra/ioctl.h
@@ -22,6 +22,10 @@
#ifndef _ZEBRA_IOCTL_H
#define _ZEBRA_IOCTL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Prototypes. */
extern void ifreq_set_name(struct ifreq *, struct interface *);
extern int if_ioctl(unsigned long, caddr_t);
@@ -53,4 +57,8 @@ extern struct connected *if_lookup_linklocal(struct interface *);
#endif /* SOLARIS_IPV6 */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_IOCTL_H */
diff --git a/zebra/ioctl_solaris.h b/zebra/ioctl_solaris.h
index 3507e563cd..363f382896 100644
--- a/zebra/ioctl_solaris.h
+++ b/zebra/ioctl_solaris.h
@@ -22,7 +22,15 @@
#ifndef _ZEBRA_IF_IOCTL_SOLARIS_H
#define _ZEBRA_IF_IOCTL_SOLARIS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void lifreq_set_name(struct lifreq *, const char *);
int if_get_flags_direct(const char *, uint64_t *, unsigned int af);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_IF_IOCTL_SOLARIS_H */
diff --git a/zebra/ipforward.h b/zebra/ipforward.h
index fe9f2db911..9884678c7a 100644
--- a/zebra/ipforward.h
+++ b/zebra/ipforward.h
@@ -21,6 +21,10 @@
#ifndef _ZEBRA_IPFORWARD_H
#define _ZEBRA_IPFORWARD_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern int ipforward(void);
extern int ipforward_on(void);
extern int ipforward_off(void);
@@ -29,4 +33,8 @@ extern int ipforward_ipv6(void);
extern int ipforward_ipv6_on(void);
extern int ipforward_ipv6_off(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_IPFORWARD_H */
diff --git a/zebra/irdp.h b/zebra/irdp.h
index 4800e75be3..3f4fa93460 100644
--- a/zebra/irdp.h
+++ b/zebra/irdp.h
@@ -28,6 +28,10 @@
#include "lib/vty.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define TRUE 1
#define FALSE 0
@@ -150,5 +154,8 @@ extern int irdp_read_raw(struct thread *r);
extern void send_packet(struct interface *ifp, struct stream *s, uint32_t dst,
struct prefix *p, uint32_t ttl);
+#ifdef __cplusplus
+}
+#endif
#endif /* _IRDP_H */
diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c
index a9734056bc..38d241eaa5 100644
--- a/zebra/irdp_main.c
+++ b/zebra/irdp_main.c
@@ -241,7 +241,7 @@ int irdp_send_thread(struct thread *t_advert)
timer = MAX_INITIAL_ADVERT_INTERVAL;
if (irdp->flags & IF_DEBUG_MISC)
- zlog_debug("IRDP: New timer for %s set to %u\n", ifp->name,
+ zlog_debug("IRDP: New timer for %s set to %u", ifp->name,
timer);
irdp->t_advertise = NULL;
diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c
index 774d84d66d..2804787620 100644
--- a/zebra/irdp_packet.c
+++ b/zebra/irdp_packet.c
@@ -166,7 +166,7 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
case ICMP_ROUTERSOLICIT:
if (irdp->flags & IF_DEBUG_MESSAGES)
- zlog_debug("IRDP: RX Solicit on %s from %s\n",
+ zlog_debug("IRDP: RX Solicit on %s from %s",
ifp->name, inet_ntoa(src));
process_solicit(ifp);
@@ -253,7 +253,7 @@ int irdp_read_raw(struct thread *r)
if (!(irdp->flags & IF_ACTIVE)) {
if (irdp->flags & IF_DEBUG_MISC)
- zlog_debug("IRDP: RX ICMP for disabled interface %s\n",
+ zlog_debug("IRDP: RX ICMP for disabled interface %s",
ifp->name);
return 0;
}
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 2f850c6338..fe37a33358 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -606,53 +606,59 @@ const char *nl_rttype_to_str(uint8_t rttype)
return lookup_msg(rttype_str, rttype, "");
}
-#define NL_OK(nla, len) \
+#define NLA_OK(nla, len) \
((len) >= (int)sizeof(struct nlattr) \
&& (nla)->nla_len >= sizeof(struct nlattr) \
&& (nla)->nla_len <= (len))
-#define NL_NEXT(nla, attrlen) \
- ((attrlen) -= RTA_ALIGN((nla)->nla_len), \
- (struct nlattr *)(((char *)(nla)) + RTA_ALIGN((nla)->nla_len)))
-#define NL_RTA(r) \
- ((struct nlattr *)(((char *)(r)) \
- + NLMSG_ALIGN(sizeof(struct nlmsgerr))))
+#define NLA_NEXT(nla, attrlen) \
+ ((attrlen) -= NLA_ALIGN((nla)->nla_len), \
+ (struct nlattr *)(((char *)(nla)) + NLA_ALIGN((nla)->nla_len)))
+#define NLA_LENGTH(len) (NLA_ALIGN(sizeof(struct nlattr)) + (len))
+#define NLA_DATA(nla) ((struct nlattr *)(((char *)(nla)) + NLA_LENGTH(0)))
+
+#define ERR_NLA(err, inner_len) \
+ ((struct nlattr *)(((char *)(err)) \
+ + NLMSG_ALIGN(sizeof(struct nlmsgerr)) \
+ + NLMSG_ALIGN((inner_len))))
static void netlink_parse_nlattr(struct nlattr **tb, int max,
struct nlattr *nla, int len)
{
- while (NL_OK(nla, len)) {
+ while (NLA_OK(nla, len)) {
if (nla->nla_type <= max)
tb[nla->nla_type] = nla;
- nla = NL_NEXT(nla, len);
+ nla = NLA_NEXT(nla, len);
}
}
static void netlink_parse_extended_ack(struct nlmsghdr *h)
{
- struct nlattr *tb[NLMSGERR_ATTR_MAX + 1];
- const struct nlmsgerr *err =
- (const struct nlmsgerr *)((uint8_t *)h
- + NLMSG_ALIGN(
- sizeof(struct nlmsghdr)));
+ struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {};
+ const struct nlmsgerr *err = (const struct nlmsgerr *)NLMSG_DATA(h);
const struct nlmsghdr *err_nlh = NULL;
- uint32_t hlen = sizeof(*err);
+ /* Length not including nlmsghdr */
+ uint32_t len = 0;
+ /* Inner error netlink message length */
+ uint32_t inner_len = 0;
const char *msg = NULL;
uint32_t off = 0;
if (!(h->nlmsg_flags & NLM_F_CAPPED))
- hlen += h->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr));
+ inner_len = (uint32_t)NLMSG_PAYLOAD(&err->msg, 0);
+
+ len = (uint32_t)(NLMSG_PAYLOAD(h, sizeof(struct nlmsgerr)) - inner_len);
- memset(tb, 0, sizeof(tb));
- netlink_parse_nlattr(tb, NLMSGERR_ATTR_MAX, NL_RTA(h), hlen);
+ netlink_parse_nlattr(tb, NLMSGERR_ATTR_MAX, ERR_NLA(err, inner_len),
+ len);
if (tb[NLMSGERR_ATTR_MSG])
- msg = (const char *)RTA_DATA(tb[NLMSGERR_ATTR_MSG]);
+ msg = (const char *)NLA_DATA(tb[NLMSGERR_ATTR_MSG]);
if (tb[NLMSGERR_ATTR_OFFS]) {
- off = *(uint32_t *)RTA_DATA(tb[NLMSGERR_ATTR_OFFS]);
+ off = *(uint32_t *)NLA_DATA(tb[NLMSGERR_ATTR_OFFS]);
if (off > h->nlmsg_len) {
- zlog_err("Invalid offset for NLMSGERR_ATTR_OFFS\n");
+ zlog_err("Invalid offset for NLMSGERR_ATTR_OFFS");
} else if (!(h->nlmsg_flags & NLM_F_CAPPED)) {
/*
* Header of failed message
diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h
index 9918729eb6..076ca5c5c7 100644
--- a/zebra/kernel_netlink.h
+++ b/zebra/kernel_netlink.h
@@ -21,6 +21,10 @@
#ifndef _ZEBRA_KERNEL_NETLINK_H
#define _ZEBRA_KERNEL_NETLINK_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifdef HAVE_NETLINK
#define NL_RCV_PKT_BUF_SIZE 32768
@@ -68,4 +72,8 @@ extern int netlink_request(struct nlsock *nl, struct nlmsghdr *n);
#endif /* HAVE_NETLINK */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_KERNEL_NETLINK_H */
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 792756efeb..1bbb98ad19 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -148,7 +148,9 @@ const struct message rtm_type_str[] = {{RTM_ADD, "RTM_ADD"},
#ifdef RTM_OLDDEL
{RTM_OLDDEL, "RTM_OLDDEL"},
#endif /* RTM_OLDDEL */
+#ifdef RTM_RESOLVE
{RTM_RESOLVE, "RTM_RESOLVE"},
+#endif /* RTM_RESOLVE */
{RTM_NEWADDR, "RTM_NEWADDR"},
{RTM_DELADDR, "RTM_DELADDR"},
{RTM_IFINFO, "RTM_IFINFO"},
@@ -622,7 +624,7 @@ int ifm_read(struct if_msghdr *ifm)
* RTA_IFP) is required.
*/
if (!ifnlen) {
- zlog_debug("Interface index %d (new) missing ifname\n",
+ zlog_debug("Interface index %d (new) missing ifname",
ifm->ifm_index);
return -1;
}
diff --git a/zebra/kernel_socket.h b/zebra/kernel_socket.h
index 096a21f782..15079d796d 100644
--- a/zebra/kernel_socket.h
+++ b/zebra/kernel_socket.h
@@ -22,6 +22,10 @@
#ifndef __ZEBRA_KERNEL_SOCKET_H
#define __ZEBRA_KERNEL_SOCKET_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Error codes of zebra. */
#define ZEBRA_ERR_NOERROR 0
#define ZEBRA_ERR_RTEXIST -1
@@ -38,4 +42,8 @@ extern int rtm_write(int, union sockunion *, union sockunion *,
enum blackhole_type, int);
extern const struct message rtm_type_str[];
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ZEBRA_KERNEL_SOCKET_H */
diff --git a/zebra/label_manager.h b/zebra/label_manager.h
index 3e3def5f98..3ea89fbfc3 100644
--- a/zebra/label_manager.h
+++ b/zebra/label_manager.h
@@ -31,6 +31,10 @@
#include "zebra/zserv.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define NO_PROTO 0
/*
@@ -74,4 +78,8 @@ int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start,
int release_daemon_label_chunks(struct zserv *client);
void label_manager_close(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _LABEL_MANAGER_H */
diff --git a/zebra/main.c b/zebra/main.c
index c605050c57..184e798bd0 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -153,7 +153,9 @@ static void sigint(void)
for (ALL_LIST_ELEMENTS(zrouter.client_list, ln, nn, client))
zserv_close_client(client);
+ zserv_close();
list_delete_all_node(zrouter.client_list);
+
zebra_ptm_finish();
if (retain_mode)
diff --git a/zebra/redistribute.h b/zebra/redistribute.h
index f0dc79574c..74a593b240 100644
--- a/zebra/redistribute.h
+++ b/zebra/redistribute.h
@@ -29,6 +29,10 @@
#include "zebra/zserv.h"
#include "zebra/rib.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* ZAPI command handlers */
extern void zebra_redistribute_add(ZAPI_HANDLER_ARGS);
extern void zebra_redistribute_delete(ZAPI_HANDLER_ARGS);
@@ -73,4 +77,9 @@ extern int is_zebra_import_table_enabled(afi_t, uint32_t table_id);
extern int zebra_import_table_config(struct vty *);
extern void zebra_import_table_rm_update(const char *rmap);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_REDISTRIBUTE_H */
diff --git a/zebra/rib.h b/zebra/rib.h
index a478fffddb..e26831e1a6 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -35,6 +35,10 @@
#include "mpls.h"
#include "srcdest_table.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define DISTANCE_INFINITY 255
#define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */
@@ -141,6 +145,15 @@ typedef struct rib_dest_t_ {
uint32_t flags;
/*
+ * The list of nht prefixes that have ended up
+ * depending on this route node.
+ * After route processing is returned from
+ * the data plane we will run evaluate_rnh
+ * on these prefixes.
+ */
+ struct list *nht;
+
+ /*
* Linkage to put dest on the FPM processing queue.
*/
TAILQ_ENTRY(rib_dest_t_) fpm_q_entries;
@@ -168,6 +181,8 @@ typedef struct rib_dest_t_ {
*/
#define RIB_DEST_UPDATE_FPM (1 << (ZEBRA_MAX_QINDEX + 2))
+#define RIB_DEST_UPDATE_LSPS (1 << (ZEBRA_MAX_QINDEX + 3))
+
/*
* Macro to iterate over each route for a destination (prefix).
*/
@@ -355,6 +370,8 @@ extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter);
extern uint8_t route_distance(int type);
+extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq);
+
/*
* Inline functions.
*/
@@ -427,6 +444,11 @@ static inline struct zebra_vrf *rib_dest_vrf(rib_dest_t *dest)
}
/*
+ * Create the rib_dest_t and attach it to the specified node
+ */
+extern rib_dest_t *zebra_rib_create_dest(struct route_node *rn);
+
+/*
* rib_tables_iter_init
*/
static inline void rib_tables_iter_init(rib_tables_iter_t *iter)
@@ -464,4 +486,9 @@ extern void zebra_vty_init(void);
extern pid_t pid;
extern bool v6_rr_semantics;
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /*_ZEBRA_RIB_H */
diff --git a/zebra/router-id.h b/zebra/router-id.h
index 6b15159fdb..f7d16853f1 100644
--- a/zebra/router-id.h
+++ b/zebra/router-id.h
@@ -30,6 +30,10 @@
#include "zclient.h"
#include "if.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern void router_id_add_address(struct connected *);
extern void router_id_del_address(struct connected *);
extern void router_id_init(struct zebra_vrf *);
@@ -37,4 +41,8 @@ extern void router_id_cmd_init(void);
extern void router_id_write(struct vty *);
extern void router_id_get(struct prefix *, vrf_id_t);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/zebra/rt.h b/zebra/rt.h
index 4080b0ccb2..2c77af2aad 100644
--- a/zebra/rt.h
+++ b/zebra/rt.h
@@ -31,6 +31,13 @@
#include "zebra/zebra_mpls.h"
#include "zebra/zebra_dplane.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RSYSTEM_ROUTE(type) \
+ ((type) == ZEBRA_ROUTE_KERNEL || (type) == ZEBRA_ROUTE_CONNECT)
+
/*
* Update or delete a route, LSP, or pseudowire from the kernel,
* using info from a dataplane context.
@@ -91,4 +98,8 @@ extern void neigh_read_specific_ip(struct ipaddr *ip,
struct interface *vlan_if);
extern void route_read(struct zebra_ns *zns);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_RT_H */
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index c56e2f316d..289ed5a15b 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -835,7 +835,7 @@ int netlink_route_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)) {
/* If this is not route add/delete message print warning. */
- zlog_debug("Kernel message: %s NS %u\n",
+ zlog_debug("Kernel message: %s NS %u",
nl_msg_type_to_str(h->nlmsg_type), ns_id);
return 0;
}
@@ -1836,7 +1836,9 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
* of the route delete. If that happens yeah we're
* screwed.
*/
- (void)netlink_route_multipath(RTM_DELROUTE, ctx);
+ if (!RSYSTEM_ROUTE(dplane_ctx_get_old_type(ctx)))
+ (void)netlink_route_multipath(RTM_DELROUTE,
+ ctx);
cmd = RTM_NEWROUTE;
}
@@ -1844,7 +1846,10 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
return ZEBRA_DPLANE_REQUEST_FAILURE;
}
- ret = netlink_route_multipath(cmd, ctx);
+ if (!RSYSTEM_ROUTE(dplane_ctx_get_type(ctx)))
+ ret = netlink_route_multipath(cmd, ctx);
+ else
+ ret = 0;
if ((cmd == RTM_NEWROUTE) && (ret == 0)) {
/* Update installed nexthops to signal which have been
* installed.
diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h
index 473ad98a3f..29e0152bb2 100644
--- a/zebra/rt_netlink.h
+++ b/zebra/rt_netlink.h
@@ -26,6 +26,10 @@
#include "zebra/zebra_mpls.h"
#include "zebra/zebra_dplane.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define NL_DEFAULT_ROUTE_METRIC 20
/*
@@ -79,6 +83,10 @@ extern int netlink_macfdb_read_specific_mac(struct zebra_ns *zns,
extern int netlink_neigh_read_specific_ip(struct ipaddr *ip,
struct interface *vlan_if);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* HAVE_NETLINK */
#endif /* _ZEBRA_RT_NETLINK_H */
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index f25259f300..8d8bdd0a6d 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -304,33 +304,41 @@ static int kernel_rtm(int cmd, const struct prefix *p,
enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
{
enum zebra_dplane_result res = ZEBRA_DPLANE_REQUEST_SUCCESS;
+ uint32_t type, old_type;
if (dplane_ctx_get_src(ctx) != NULL) {
zlog_err("route add: IPv6 sourcedest routes unsupported!");
return ZEBRA_DPLANE_REQUEST_FAILURE;
}
+ type = dplane_ctx_get_type(ctx);
+ old_type = dplane_ctx_get_old_type(ctx);
+
frr_elevate_privs(&zserv_privs) {
- if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_DELETE)
- kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
- dplane_ctx_get_ng(ctx),
- dplane_ctx_get_metric(ctx));
- else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_INSTALL)
- kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
- dplane_ctx_get_ng(ctx),
- dplane_ctx_get_metric(ctx));
- else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_UPDATE) {
+ if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_DELETE) {
+ if (!RSYSTEM_ROUTE(type))
+ kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
+ dplane_ctx_get_ng(ctx),
+ dplane_ctx_get_metric(ctx));
+ } else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_INSTALL) {
+ if (!RSYSTEM_ROUTE(type))
+ kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
+ dplane_ctx_get_ng(ctx),
+ dplane_ctx_get_metric(ctx));
+ } else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_UPDATE) {
/* Must do delete and add separately -
* no update available
*/
- kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
- dplane_ctx_get_old_ng(ctx),
- dplane_ctx_get_old_metric(ctx));
-
- kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
- dplane_ctx_get_ng(ctx),
- dplane_ctx_get_metric(ctx));
+ if (!RSYSTEM_ROUTE(old_type))
+ kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
+ dplane_ctx_get_old_ng(ctx),
+ dplane_ctx_get_old_metric(ctx));
+
+ if (!RSYSTEM_ROUTE(type))
+ kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
+ dplane_ctx_get_ng(ctx),
+ dplane_ctx_get_metric(ctx));
} else {
zlog_err("Invalid routing socket update op %s (%u)",
dplane_op2str(dplane_ctx_get_op(ctx)),
@@ -339,6 +347,20 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
}
} /* Elevated privs */
+ if (RSYSTEM_ROUTE(type)
+ && dplane_ctx_get_op(ctx) != DPLANE_OP_ROUTE_DELETE) {
+ struct nexthop *nexthop;
+
+ for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ continue;
+
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) {
+ SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
+ }
+ }
+ }
+
return res;
}
diff --git a/zebra/rtadv.h b/zebra/rtadv.h
index f7c27ebcb3..53c497fc09 100644
--- a/zebra/rtadv.h
+++ b/zebra/rtadv.h
@@ -25,6 +25,10 @@
#include "vty.h"
#include "zebra/interface.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* NB: RTADV is defined in zebra/interface.h above */
#if defined(HAVE_RTADV)
@@ -137,5 +141,8 @@ extern void rtadv_cmd_init(void);
extern void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS);
extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS);
+#ifdef __cplusplus
+}
+#endif
#endif /* _ZEBRA_RTADV_H */
diff --git a/zebra/rule_netlink.h b/zebra/rule_netlink.h
index 4547a1bb3b..8c4741dc06 100644
--- a/zebra/rule_netlink.h
+++ b/zebra/rule_netlink.h
@@ -26,6 +26,10 @@
#ifdef HAVE_NETLINK
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Handle netlink notification informing a rule add or delete.
*/
@@ -36,6 +40,10 @@ extern int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup);
*/
extern int netlink_rules_read(struct zebra_ns *zns);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* HAVE_NETLINK */
#endif /* _ZEBRA_RULE_NETLINK_H */
diff --git a/zebra/table_manager.h b/zebra/table_manager.h
index 5196162c4c..4f78f5097e 100644
--- a/zebra/table_manager.h
+++ b/zebra/table_manager.h
@@ -27,6 +27,10 @@
#include "zebra/zserv.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Table chunk struct
* Client daemon which the chunk belongs to can be identified by either
@@ -63,4 +67,8 @@ int release_table_chunk(uint8_t proto, uint16_t instance, uint32_t start,
int release_daemon_table_chunks(struct zserv *client);
void table_manager_disable(ns_id_t ns_id);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _TABLE_MANAGER_H */
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 9f2bbcf426..2eeb1f2788 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -1036,6 +1036,8 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
uint8_t flags = 0;
uint16_t type = cmd2type[hdr->command];
bool exist;
+ bool flag_changed = false;
+ uint8_t orig_flags;
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug(
@@ -1084,6 +1086,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
if (!rnh)
return;
+ orig_flags = rnh->flags;
if (type == RNH_NEXTHOP_TYPE) {
if (flags
&& !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
@@ -1101,9 +1104,12 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
}
+ if (orig_flags != rnh->flags)
+ flag_changed = true;
+
zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf));
/* Anything not AF_INET/INET6 has been filtered out above */
- if (!exist)
+ if (!exist || flag_changed)
zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, type,
&p);
}
@@ -1456,8 +1462,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
&(api_nh->gate.ipv4),
sizeof(struct in_addr));
zebra_vxlan_evpn_vrf_route_add(
- vrf_id, &api_nh->rmac, &vtep_ip,
- &api.prefix);
+ api_nh->vrf_id, &api_nh->rmac,
+ &vtep_ip, &api.prefix);
}
break;
case NEXTHOP_TYPE_IPV6:
@@ -1479,8 +1485,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
memcpy(&vtep_ip.ipaddr_v6, &(api_nh->gate.ipv6),
sizeof(struct in6_addr));
zebra_vxlan_evpn_vrf_route_add(
- vrf_id, &api_nh->rmac, &vtep_ip,
- &api.prefix);
+ api_nh->vrf_id, &api_nh->rmac,
+ &vtep_ip, &api.prefix);
}
break;
case NEXTHOP_TYPE_BLACKHOLE:
diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h
index b770b8e881..d30fa2d0ef 100644
--- a/zebra/zapi_msg.h
+++ b/zebra/zapi_msg.h
@@ -30,6 +30,10 @@
#include "zebra/zebra_pbr.h"
#include "zebra/zebra_errors.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* This is called to process inbound ZAPI messages.
*
@@ -86,3 +90,7 @@ extern void zserv_nexthop_num_warn(const char *caller, const struct prefix *p,
const unsigned int nexthop_num);
extern void zsend_capabilities_all_clients(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index 149ff8dc60..1246fcc8ec 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -30,6 +30,10 @@
#include "zebra/zserv.h"
#include "zebra/zebra_mpls.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Key netlink info from zebra ns */
struct zebra_dplane_info {
ns_id_t ns_id;
@@ -394,4 +398,8 @@ void zebra_dplane_pre_finish(void);
void zebra_dplane_finish(void);
void zebra_dplane_shutdown(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_DPLANE_H */
diff --git a/zebra/zebra_errors.h b/zebra/zebra_errors.h
index 0af5f8a551..2b7831a408 100644
--- a/zebra/zebra_errors.h
+++ b/zebra/zebra_errors.h
@@ -23,6 +23,10 @@
#include "lib/ferr.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
enum zebra_log_refs {
EC_ZEBRA_LM_RESPONSE = ZEBRA_FERR_START,
EC_ZEBRA_LM_NO_SUCH_CLIENT,
@@ -126,4 +130,8 @@ enum zebra_log_refs {
void zebra_error_init(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __EC_ZEBRAORS_H__ */
diff --git a/zebra/zebra_fpm_private.h b/zebra/zebra_fpm_private.h
index 969ab6cfee..943aad9864 100644
--- a/zebra/zebra_fpm_private.h
+++ b/zebra/zebra_fpm_private.h
@@ -26,6 +26,10 @@
#include "zebra/debug.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#define zfpm_debug(...) \
@@ -61,4 +65,9 @@ extern int zfpm_protobuf_encode_route(rib_dest_t *dest, struct route_entry *re,
uint8_t *in_buf, size_t in_buf_len);
extern struct route_entry *zfpm_route_for_update(rib_dest_t *dest);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_FPM_PRIVATE_H */
diff --git a/zebra/zebra_l2.h b/zebra/zebra_l2.h
index 68c9d4a7a1..2e3e5b4a85 100644
--- a/zebra/zebra_l2.h
+++ b/zebra/zebra_l2.h
@@ -29,6 +29,10 @@
#include "vlan.h"
#include "vxlan.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* zebra L2 interface information - bridge slave (linkage to bridge) */
struct zebra_l2info_brslave {
ifindex_t bridge_ifindex; /* Bridge Master */
@@ -96,4 +100,9 @@ extern void zebra_l2if_update_bridge_slave(struct interface *ifp,
extern void zebra_l2if_update_bond_slave(struct interface *ifp,
ifindex_t bond_ifindex);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_L2_H */
diff --git a/zebra/zebra_memory.h b/zebra/zebra_memory.h
index de55478de2..667c73b227 100644
--- a/zebra/zebra_memory.h
+++ b/zebra/zebra_memory.h
@@ -24,6 +24,10 @@
#include "memory.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
DECLARE_MGROUP(ZEBRA)
DECLARE_MTYPE(RTADV_PREFIX)
DECLARE_MTYPE(ZEBRA_NS)
@@ -37,4 +41,8 @@ DECLARE_MTYPE(RNH)
DECLARE_MTYPE(DP_CTX)
DECLARE_MTYPE(DP_PROV)
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _QUAGGA_ZEBRA_MEMORY_H */
diff --git a/zebra/zebra_mlag.h b/zebra/zebra_mlag.h
index c5c147c833..90a5a41fa4 100644
--- a/zebra/zebra_mlag.h
+++ b/zebra/zebra_mlag.h
@@ -24,8 +24,17 @@
#include "mlag.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void zebra_mlag_init(void);
void zebra_mlag_terminate(void);
enum mlag_role zebra_mlag_get_role(void);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index 39f084ad2f..3a131e1aaf 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -34,6 +34,9 @@
#include "zebra/zserv.h"
#include "zebra/zebra_vrf.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
/* Definitions and macros. */
@@ -507,31 +510,48 @@ static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type)
return "Unknown";
}
-static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf)
+static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf,
+ struct prefix *p)
{
+ struct route_table *table;
+ struct route_node *rn;
+ rib_dest_t *dest;
+
if (!zvrf)
return;
- zvrf->mpls_flags |= MPLS_FLAG_SCHEDULE_LSPS;
+ table = zvrf->table[family2afi(p->family)][SAFI_UNICAST];
+ if (!table)
+ return;
+
+ rn = route_node_match(table, p);
+ if (!rn)
+ return;
+
+
+ dest = rib_dest_from_rnode(rn);
+ SET_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
}
-static inline void mpls_unmark_lsps_for_processing(struct zebra_vrf *zvrf)
+static inline void mpls_unmark_lsps_for_processing(struct route_node *rn)
{
- if (!zvrf)
- return;
+ rib_dest_t *dest = rib_dest_from_rnode(rn);
- zvrf->mpls_flags &= ~MPLS_FLAG_SCHEDULE_LSPS;
+ UNSET_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
}
-static inline int mpls_should_lsps_be_processed(struct zebra_vrf *zvrf)
+static inline int mpls_should_lsps_be_processed(struct route_node *rn)
{
- if (!zvrf)
- return 0;
+ rib_dest_t *dest = rib_dest_from_rnode(rn);
- return ((zvrf->mpls_flags & MPLS_FLAG_SCHEDULE_LSPS) ? 1 : 0);
+ return !!CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
}
/* Global variables. */
extern int mpls_enabled;
+#ifdef __cplusplus
+}
+#endif
+
#endif /*_ZEBRA_MPLS_H */
diff --git a/zebra/zebra_mroute.h b/zebra/zebra_mroute.h
index 3385153600..3c12b82da3 100644
--- a/zebra/zebra_mroute.h
+++ b/zebra/zebra_mroute.h
@@ -24,6 +24,10 @@
#include "zebra/zserv.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct mcast_route_data {
struct prefix_sg sg;
unsigned int ifindex;
@@ -32,4 +36,8 @@ struct mcast_route_data {
void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/zebra/zebra_netns_id.h b/zebra/zebra_netns_id.h
index d6530e6694..7a5f6851f4 100644
--- a/zebra/zebra_netns_id.h
+++ b/zebra/zebra_netns_id.h
@@ -20,7 +20,15 @@
#include "zebra.h"
#include "ns.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern ns_id_t zebra_ns_id_get(const char *netnspath);
extern ns_id_t zebra_ns_id_get_default(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ZEBRA_NS_ID_H__ */
diff --git a/zebra/zebra_netns_notify.h b/zebra/zebra_netns_notify.h
index 0ced749ae8..18939283a7 100644
--- a/zebra/zebra_netns_notify.h
+++ b/zebra/zebra_netns_notify.h
@@ -20,10 +20,18 @@
#ifndef _NETNS_NOTIFY_H
#define _NETNS_NOTIFY_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern void zebra_ns_notify_init(void);
extern void zebra_ns_notify_parse(void);
extern void zebra_ns_notify_close(void);
extern struct zebra_privs_t zserv_privs;
+#ifdef __cplusplus
+}
+#endif
+
#endif /* NETNS_NOTIFY_H */
diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h
index 01af64c17b..dc79a83db0 100644
--- a/zebra/zebra_ns.h
+++ b/zebra/zebra_ns.h
@@ -28,6 +28,10 @@
#include "zebra/rib.h"
#include "zebra/zebra_vrf.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifdef HAVE_NETLINK
/* Socket interface to kernel */
struct nlsock {
@@ -68,4 +72,8 @@ int zebra_ns_final_shutdown(struct ns *ns);
int zebra_ns_config_write(struct vty *vty, struct ns *ns);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index 5b6c23896c..0d55491107 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -32,6 +32,10 @@
#include "rt.h"
#include "pbr.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct zebra_pbr_rule {
int sock;
@@ -252,4 +256,8 @@ DECLARE_HOOK(zebra_pbr_ipset_entry_update,
DECLARE_HOOK(zebra_pbr_ipset_update,
(int cmd, struct zebra_pbr_ipset *ipset), (cmd, ipset));
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_PBR_H */
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index cc5e38e690..bb352dc2ff 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -328,7 +328,7 @@ DEFUN (zebra_ptm_enable_if,
if (!old_ptm_enable && ptm_cb.ptm_enable) {
if (!if_is_operative(ifp) && send_linkdown) {
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("%s: Bringing down interface %s\n",
+ zlog_debug("%s: Bringing down interface %s",
__func__, ifp->name);
if_down(ifp);
}
@@ -354,7 +354,7 @@ DEFUN (no_zebra_ptm_enable_if,
ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF;
if (if_is_no_ptm_operative(ifp) && send_linkup) {
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("%s: Bringing up interface %s\n",
+ zlog_debug("%s: Bringing up interface %s",
__func__, ifp->name);
if_up(ifp);
}
diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h
index d0cdaf0bce..e578a02a94 100644
--- a/zebra/zebra_ptm.h
+++ b/zebra/zebra_ptm.h
@@ -31,6 +31,10 @@ extern const char ZEBRA_PTM_SOCK_NAME[];
#include "zebra/zserv.h"
#include "zebra/interface.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Zebra ptm context block */
struct zebra_ptm_cb {
int ptm_sock; /* ptm file descriptor. */
@@ -87,4 +91,9 @@ void zebra_ptm_if_init(struct zebra_if *zebra_ifp);
void zebra_ptm_if_set_ptm_state(struct interface *ifp,
struct zebra_if *zebra_ifp);
void zebra_ptm_if_write(struct vty *vty, struct zebra_if *zebra_ifp);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/zebra/zebra_ptm_redistribute.h b/zebra/zebra_ptm_redistribute.h
index c1b12bd0d1..4daf405825 100644
--- a/zebra/zebra_ptm_redistribute.h
+++ b/zebra/zebra_ptm_redistribute.h
@@ -21,7 +21,17 @@
#ifndef _ZEBRA_PTM_REDISTRIBUTE_H
#define _ZEBRA_PTM_REDISTRIBUTE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern void zebra_interface_bfd_update(struct interface *, struct prefix *,
struct prefix *, int, vrf_id_t);
extern void zebra_bfd_peer_replay_req(void);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_PTM_REDISTRIBUTE_H */
diff --git a/zebra/zebra_pw.h b/zebra/zebra_pw.h
index 9692fb4d40..bbb3776725 100644
--- a/zebra/zebra_pw.h
+++ b/zebra/zebra_pw.h
@@ -29,6 +29,10 @@
#include "zebra/zebra_vrf.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define PW_INSTALL_RETRY_INTERVAL 30
struct zebra_pw {
@@ -74,4 +78,8 @@ void zebra_pw_init(struct zebra_vrf *);
void zebra_pw_exit(struct zebra_vrf *);
void zebra_pw_vty_init(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* ZEBRA_PW_H_ */
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 2014aa3bed..557e6876e2 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1175,10 +1175,7 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re)
if (zebra_rib_labeled_unicast(re))
zebra_mpls_lsp_uninstall(info->zvrf, rn, re);
- if (!RIB_SYSTEM_ROUTE(re))
- rib_uninstall_kernel(rn, re);
- else
- UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+ rib_uninstall_kernel(rn, re);
dest->selected_fib = NULL;
@@ -1208,6 +1205,16 @@ static int rib_can_delete_dest(rib_dest_t *dest)
}
/*
+ * Unresolved rnh's are stored on the default route's list
+ *
+ * dest->rnode can also be the source prefix node in an
+ * ipv6 sourcedest table. Fortunately the prefix of a
+ * source prefix node can never be the default prefix.
+ */
+ if (is_default_prefix(&dest->rnode->p))
+ return 0;
+
+ /*
* Don't delete the dest if we have to update the FPM about this
* prefix.
*/
@@ -1218,6 +1225,88 @@ static int rib_can_delete_dest(rib_dest_t *dest)
return 1;
}
+void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq)
+{
+ rib_dest_t *dest = rib_dest_from_rnode(rn);
+ struct listnode *node, *nnode;
+ struct rnh *rnh;
+
+ /*
+ * We are storing the rnh's associated withb
+ * the tracked nexthop as a list of the rn's.
+ * Unresolved rnh's are placed at the top
+ * of the tree list.( 0.0.0.0/0 for v4 and 0::0/0 for v6 )
+ * As such for each rn we need to walk up the tree
+ * and see if any rnh's need to see if they
+ * would match a more specific route
+ */
+ while (rn) {
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+ char buf[PREFIX_STRLEN];
+
+ zlog_debug("%s: %s Being examined for Nexthop Tracking",
+ __PRETTY_FUNCTION__,
+ srcdest_rnode2str(rn, buf, sizeof(buf)));
+ }
+ if (!dest) {
+ rn = rn->parent;
+ if (rn)
+ dest = rib_dest_from_rnode(rn);
+ continue;
+ }
+ /*
+ * If we have any rnh's stored in the nht list
+ * then we know that this route node was used for
+ * nht resolution and as such we need to call the
+ * nexthop tracking evaluation code
+ */
+ for (ALL_LIST_ELEMENTS(dest->nht, node, nnode, rnh)) {
+ struct zebra_vrf *zvrf =
+ zebra_vrf_lookup_by_id(rnh->vrf_id);
+ struct prefix *p = &rnh->node->p;
+
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+ char buf1[PREFIX_STRLEN];
+ char buf2[PREFIX_STRLEN];
+
+ zlog_debug("%u:%s has Nexthop(%s) depending on it, evaluating %u:%u",
+ zvrf->vrf->vrf_id,
+ srcdest_rnode2str(rn, buf1,
+ sizeof(buf1)),
+ prefix2str(p, buf2, sizeof(buf2)),
+ seq, rnh->seqno);
+ }
+
+ /*
+ * If we have evaluated this node on this pass
+ * already, due to following the tree up
+ * then we know that we can move onto the next
+ * rnh to process.
+ *
+ * Additionally we call zebra_evaluate_rnh
+ * when we gc the dest. In this case we know
+ * that there must be no other re's where
+ * we were originally as such we know that
+ * that sequence number is ok to respect.
+ */
+ if (rnh->seqno == seq) {
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+ zlog_debug(
+ "\tNode processed and moved already");
+ continue;
+ }
+
+ rnh->seqno = seq;
+ zebra_evaluate_rnh(zvrf, family2afi(p->family), 0,
+ rnh->type, p);
+ }
+
+ rn = rn->parent;
+ if (rn)
+ dest = rib_dest_from_rnode(rn);
+ }
+}
+
/*
* rib_gc_dest
*
@@ -1244,7 +1333,10 @@ int rib_gc_dest(struct route_node *rn)
rnode_debug(rn, zvrf_id(zvrf), "removing dest from table");
}
+ zebra_rib_evaluate_rn_nexthops(rn, zebra_router_get_next_sequence());
+
dest->rnode = NULL;
+ list_delete(&dest->nht);
XFREE(MTYPE_RIB_DEST, dest);
rn->info = NULL;
@@ -1258,8 +1350,6 @@ int rib_gc_dest(struct route_node *rn)
static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
struct route_entry *new)
{
- rib_dest_t *dest = rib_dest_from_rnode(rn);
-
hook_call(rib_update, rn, "new route selected");
/* Update real nexthop. This may actually determine if nexthop is active
@@ -1281,10 +1371,7 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
if (zebra_rib_labeled_unicast(new))
zebra_mpls_lsp_install(zvrf, rn, new);
- if (!RIB_SYSTEM_ROUTE(new))
- rib_install_kernel(rn, new, NULL);
- else
- dest->selected_fib = new;
+ rib_install_kernel(rn, new, NULL);
UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
}
@@ -1292,7 +1379,6 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
struct route_entry *old)
{
- rib_dest_t *dest = rib_dest_from_rnode(rn);
hook_call(rib_update, rn, "removing existing route");
/* Uninstall from kernel. */
@@ -1308,20 +1394,7 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
if (zebra_rib_labeled_unicast(old))
zebra_mpls_lsp_uninstall(zvrf, rn, old);
- if (!RIB_SYSTEM_ROUTE(old))
- rib_uninstall_kernel(rn, old);
- else {
- UNSET_FLAG(old->status, ROUTE_ENTRY_INSTALLED);
- /*
- * We are setting this to NULL here
- * because that is what we traditionally
- * have been doing. I am not positive
- * that this is the right thing to do
- * but let's leave the code alone
- * for the RIB_SYSTEM_ROUTE case
- */
- dest->selected_fib = NULL;
- }
+ rib_uninstall_kernel(rn, old);
/* Update nexthop for route, reset changed flag. */
/* Note: this code also handles the Linux case when an interface goes
@@ -1340,9 +1413,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
struct route_entry *old,
struct route_entry *new)
{
- struct nexthop *nexthop = NULL;
int nh_active = 0;
- rib_dest_t *dest = rib_dest_from_rnode(rn);
/*
* We have to install or update if a new route has been selected or
@@ -1384,48 +1455,15 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
if (zebra_rib_labeled_unicast(old))
zebra_mpls_lsp_uninstall(zvrf, rn, old);
- /* Non-system route should be installed. */
- if (!RIB_SYSTEM_ROUTE(new)) {
- /* If labeled-unicast route, install transit
- * LSP. */
- if (zebra_rib_labeled_unicast(new))
- zebra_mpls_lsp_install(zvrf, rn, new);
+ /*
+ * Non-system route should be installed.
+ * If labeled-unicast route, install transit
+ * LSP.
+ */
+ if (zebra_rib_labeled_unicast(new))
+ zebra_mpls_lsp_install(zvrf, rn, new);
- rib_install_kernel(rn, new, old);
- } else {
- UNSET_FLAG(new->status, ROUTE_ENTRY_INSTALLED);
- /*
- * We do not need to install the
- * selected route because it
- * is already isntalled by
- * the system( ie not us )
- * so just mark it as winning
- * we do need to ensure that
- * if we uninstall a route
- * from ourselves we don't
- * over write this pointer
- */
- dest->selected_fib = NULL;
- }
- /* If install succeeded or system route, cleanup flags
- * for prior route. */
- if (new != old) {
- if (RIB_SYSTEM_ROUTE(new)) {
- if (!RIB_SYSTEM_ROUTE(old))
- rib_uninstall_kernel(rn, old);
- else
- UNSET_FLAG(
- old->status,
- ROUTE_ENTRY_INSTALLED);
- } else {
- UNSET_FLAG(old->status,
- ROUTE_ENTRY_INSTALLED);
- for (nexthop = old->ng.nexthop; nexthop;
- nexthop = nexthop->next)
- UNSET_FLAG(nexthop->flags,
- NEXTHOP_FLAG_FIB);
- }
- }
+ rib_install_kernel(rn, new, old);
}
/*
@@ -1455,25 +1493,18 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
if (zebra_rib_labeled_unicast(old))
zebra_mpls_lsp_uninstall(zvrf, rn, old);
- if (!RIB_SYSTEM_ROUTE(old))
- rib_uninstall_kernel(rn, old);
- else {
- UNSET_FLAG(old->status, ROUTE_ENTRY_INSTALLED);
- dest->selected_fib = NULL;
- }
+ rib_uninstall_kernel(rn, old);
}
} else {
/*
* Same route selected; check if in the FIB and if not,
- * re-install. This
- * is housekeeping code to deal with race conditions in kernel
- * with linux
- * netlink reporting interface up before IPv4 or IPv6 protocol
- * is ready
+ * re-install. This is housekeeping code to deal with
+ * race conditions in kernel with linux netlink reporting
+ * interface up before IPv4 or IPv6 protocol is ready
* to add routes.
*/
- if (!RIB_SYSTEM_ROUTE(new)
- && !CHECK_FLAG(new->status, ROUTE_ENTRY_INSTALLED))
+ if (!CHECK_FLAG(new->status, ROUTE_ENTRY_INSTALLED) ||
+ RIB_SYSTEM_ROUTE(new))
rib_install_kernel(rn, new, NULL);
}
@@ -1725,18 +1756,9 @@ static void rib_process(struct route_node *rn)
UNSET_FLAG(new_selected->status, ROUTE_ENTRY_CHANGED);
}
- if (new_selected) {
+ if (new_selected)
SET_FLAG(new_selected->flags, ZEBRA_FLAG_SELECTED);
- /* Special case: new route is system route, so
- * dataplane update will not be done - ensure we
- * redistribute the route.
- */
- if (RIB_SYSTEM_ROUTE(new_selected))
- redistribute_update(p, src_p, new_selected,
- old_selected);
- }
-
if (old_selected) {
if (!new_selected)
redistribute_delete(p, src_p, old_selected);
@@ -1763,6 +1785,24 @@ static void rib_process(struct route_node *rn)
rib_gc_dest(rn);
}
+static void zebra_rib_evaluate_mpls(struct route_node *rn)
+{
+ rib_dest_t *dest = rib_dest_from_rnode(rn);
+ struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
+
+ if (!dest)
+ return;
+
+ if (CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS)) {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug(
+ "%u: Scheduling all LSPs upon RIB completion",
+ zvrf_id(zvrf));
+ zebra_mpls_lsp_schedule(zvrf);
+ mpls_unmark_lsps_for_processing(rn);
+ }
+}
+
/*
* Utility to match route with dplane context data
*/
@@ -1821,6 +1861,30 @@ done:
return (result);
}
+static void zebra_rib_fixup_system(struct route_node *rn)
+{
+ struct route_entry *re;
+
+ RNODE_FOREACH_RE(rn, re) {
+ struct nexthop *nhop;
+
+ if (!RIB_SYSTEM_ROUTE(re))
+ continue;
+
+ if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
+ continue;
+
+ SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+
+ for (ALL_NEXTHOPS(re->ng, nhop)) {
+ if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE))
+ continue;
+
+ SET_FLAG(nhop->flags, NEXTHOP_FLAG_FIB);
+ }
+ }
+}
+
/*
* Route-update results processing after async dataplane update.
*/
@@ -1836,6 +1900,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
enum dplane_op_e op;
enum zebra_dplane_result status;
const struct prefix *dest_pfx, *src_pfx;
+ uint32_t seq;
/* Locate rn and re(s) from ctx */
@@ -1912,11 +1977,13 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
break;
}
+ seq = dplane_ctx_get_seq(ctx);
+
/*
* Check sequence number(s) to detect stale results before continuing
*/
if (re) {
- if (re->dplane_sequence != dplane_ctx_get_seq(ctx)) {
+ if (re->dplane_sequence != seq) {
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
zlog_debug("%u:%s Stale dplane result for re %p",
dplane_ctx_get_vrf(ctx),
@@ -1932,7 +1999,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
dplane_ctx_get_vrf(ctx),
dest_str, old_re);
} else
- UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
+ UNSET_FLAG(old_re->status, ROUTE_ENTRY_QUEUED);
}
switch (op) {
@@ -1987,6 +2054,17 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
NEXTHOP_FLAG_FIB);
}
+ /*
+ * System routes are weird in that they
+ * allow multiple to be installed that match
+ * to the same prefix, so after we get the
+ * result we need to clean them up so that
+ * we can actually use them.
+ */
+ if ((re && RIB_SYSTEM_ROUTE(re)) ||
+ (old_re && RIB_SYSTEM_ROUTE(old_re)))
+ zebra_rib_fixup_system(rn);
+
if (zvrf) {
zvrf->installs++;
/* Set flag for nexthop tracking processing */
@@ -2010,9 +2088,10 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_INSTALLED);
} else {
- if (re)
+ if (re) {
SET_FLAG(re->status, ROUTE_ENTRY_FAILED);
- if (old_re)
+ UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+ } if (old_re)
SET_FLAG(old_re->status, ROUTE_ENTRY_FAILED);
if (re)
zsend_route_notify_owner(re, dest_pfx,
@@ -2052,10 +2131,24 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
prefix2str(dest_pfx,
dest_str, sizeof(dest_str)));
}
+
+ /*
+ * System routes are weird in that they
+ * allow multiple to be installed that match
+ * to the same prefix, so after we get the
+ * result we need to clean them up so that
+ * we can actually use them.
+ */
+ if ((re && RIB_SYSTEM_ROUTE(re)) ||
+ (old_re && RIB_SYSTEM_ROUTE(old_re)))
+ zebra_rib_fixup_system(rn);
break;
default:
break;
}
+
+ zebra_rib_evaluate_rn_nexthops(rn, seq);
+ zebra_rib_evaluate_mpls(rn);
done:
if (rn)
@@ -2110,47 +2203,12 @@ static unsigned int process_subq(struct list *subq, uint8_t qindex)
return 1;
}
+
/*
* Perform next-hop tracking processing after RIB updates.
*/
static void do_nht_processing(void)
{
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- /* Evaluate nexthops for those VRFs which underwent route processing.
- * This
- * should limit the evaluation to the necessary VRFs in most common
- * situations.
- */
- RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
- zvrf = vrf->info;
- if (zvrf == NULL || !(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED))
- continue;
-
- if (IS_ZEBRA_DEBUG_RIB_DETAILED || IS_ZEBRA_DEBUG_NHT)
- zlog_debug("NHT processing check for zvrf %s",
- zvrf_name(zvrf));
-
- zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED;
- zebra_evaluate_rnh(zvrf, AFI_IP, 0, RNH_NEXTHOP_TYPE, NULL);
- zebra_evaluate_rnh(zvrf, AFI_IP, 0, RNH_IMPORT_CHECK_TYPE,
- NULL);
- zebra_evaluate_rnh(zvrf, AFI_IP6, 0, RNH_NEXTHOP_TYPE, NULL);
- zebra_evaluate_rnh(zvrf, AFI_IP6, 0, RNH_IMPORT_CHECK_TYPE,
- NULL);
- }
-
- /* Schedule LSPs for processing, if needed. */
- zvrf = vrf_info_lookup(VRF_DEFAULT);
- if (mpls_should_lsps_be_processed(zvrf)) {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug(
- "%u: Scheduling all LSPs upon RIB completion",
- zvrf_id(zvrf));
- zebra_mpls_lsp_schedule(zvrf);
- mpls_unmark_lsps_for_processing(zvrf);
- }
}
/* Dispatch the meta queue by picking, processing and unlocking the next RN from
@@ -2340,6 +2398,19 @@ static void rib_queue_init(void)
return;
}
+rib_dest_t *zebra_rib_create_dest(struct route_node *rn)
+{
+ rib_dest_t *dest;
+
+ dest = XCALLOC(MTYPE_RIB_DEST, sizeof(rib_dest_t));
+ dest->nht = list_new();
+ route_lock_node(rn); /* rn route table reference */
+ rn->info = dest;
+ dest->rnode = rn;
+
+ return dest;
+}
+
/* RIB updates are processed via a queue of pointers to route_nodes.
*
* The queue length is bounded by the maximal size of the routing table,
@@ -2392,10 +2463,7 @@ static void rib_link(struct route_node *rn, struct route_entry *re, int process)
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
rnode_debug(rn, re->vrf_id, "rn %p adding dest", rn);
- dest = XCALLOC(MTYPE_RIB_DEST, sizeof(rib_dest_t));
- route_lock_node(rn); /* rn route table reference */
- rn->info = dest;
- dest->rnode = rn;
+ dest = zebra_rib_create_dest(rn);
}
head = dest->routes;
@@ -2654,7 +2722,7 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id)
* revalidation
* of the rest of the RE.
*/
- if (dest->selected_fib && !RIB_SYSTEM_ROUTE(dest->selected_fib)) {
+ if (dest->selected_fib) {
changed = 1;
if (IS_ZEBRA_DEBUG_RIB) {
char buf[PREFIX_STRLEN];
@@ -2676,7 +2744,6 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
struct route_table *table;
struct route_node *rn;
struct route_entry *same = NULL;
- struct nexthop *nexthop;
int ret = 0;
if (!re)
@@ -2740,13 +2807,6 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
break;
}
- /* If this route is kernel route, set FIB flag to the route. */
- if (RIB_SYSTEM_ROUTE(re)) {
- SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
- for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
- SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
- }
-
/* Link new re to node.*/
if (IS_ZEBRA_DEBUG_RIB) {
rnode_debug(rn, re->vrf_id,
@@ -3222,10 +3282,8 @@ void rib_close_table(struct route_table *table)
if (info->safi == SAFI_UNICAST)
hook_call(rib_update, rn, NULL);
- if (!RIB_SYSTEM_ROUTE(dest->selected_fib)) {
- rib_uninstall_kernel(rn, dest->selected_fib);
- dest->selected_fib = NULL;
- }
+ rib_uninstall_kernel(rn, dest->selected_fib);
+ dest->selected_fib = NULL;
}
}
}
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 52637c6062..a1519e45cd 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -94,6 +94,61 @@ char *rnh_str(struct rnh *rnh, char *buf, int size)
return buf;
}
+static void zebra_rnh_remove_from_routing_table(struct rnh *rnh)
+{
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id);
+ struct route_table *table = zvrf->table[rnh->afi][SAFI_UNICAST];
+ struct route_node *rn;
+ rib_dest_t *dest;
+
+ if (!table)
+ return;
+
+ rn = route_node_match(table, &rnh->resolved_route);
+ if (!rn)
+ return;
+
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+ char buf[PREFIX_STRLEN];
+ char buf1[PREFIX_STRLEN];
+
+ zlog_debug("%s: %u:%s removed from tracking on %s",
+ __PRETTY_FUNCTION__, rnh->vrf_id,
+ prefix2str(&rnh->node->p, buf, sizeof(buf)),
+ srcdest_rnode2str(rn, buf1, sizeof(buf)));
+ }
+
+ dest = rib_dest_from_rnode(rn);
+ listnode_delete(dest->nht, rnh);
+ route_unlock_node(rn);
+}
+
+static void zebra_rnh_store_in_routing_table(struct rnh *rnh)
+{
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id);
+ struct route_table *table = zvrf->table[rnh->afi][SAFI_UNICAST];
+ struct route_node *rn;
+ rib_dest_t *dest;
+
+ rn = route_node_match(table, &rnh->resolved_route);
+ if (!rn)
+ return;
+
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+ char buf[PREFIX_STRLEN];
+ char buf1[PREFIX_STRLEN];
+
+ zlog_debug("%s: %u:%s added for tracking on %s",
+ __PRETTY_FUNCTION__, rnh->vrf_id,
+ prefix2str(&rnh->node->p, buf, sizeof(buf)),
+ srcdest_rnode2str(rn, buf1, sizeof(buf)));
+ }
+
+ dest = rib_dest_from_rnode(rn);
+ listnode_add(dest->nht, rnh);
+ route_unlock_node(rn);
+}
+
struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type,
bool *exists)
{
@@ -101,12 +156,13 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type,
struct route_node *rn;
struct rnh *rnh = NULL;
char buf[PREFIX2STR_BUFFER];
+ afi_t afi = family2afi(p->family);
if (IS_ZEBRA_DEBUG_NHT) {
prefix2str(p, buf, sizeof(buf));
zlog_debug("%u: Add RNH %s type %d", vrfid, buf, type);
}
- table = get_rnh_table(vrfid, family2afi(PREFIX_FAMILY(p)), type);
+ table = get_rnh_table(vrfid, afi, type);
if (!table) {
prefix2str(p, buf, sizeof(buf));
flog_warn(EC_ZEBRA_RNH_NO_TABLE,
@@ -124,13 +180,26 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type,
if (!rn->info) {
rnh = XCALLOC(MTYPE_RNH, sizeof(struct rnh));
+
+ /*
+ * The resolved route is already 0.0.0.0/0 or
+ * 0::0/0 due to the calloc right above, but
+ * we should set the family so that future
+ * comparisons can just be done
+ */
+ rnh->resolved_route.family = p->family;
rnh->client_list = list_new();
rnh->vrf_id = vrfid;
+ rnh->type = type;
+ rnh->seqno = 0;
+ rnh->afi = afi;
rnh->zebra_pseudowire_list = list_new();
route_lock_node(rn);
rn->info = rnh;
rnh->node = rn;
*exists = false;
+
+ zebra_rnh_store_in_routing_table(rnh);
} else
*exists = true;
@@ -161,9 +230,30 @@ struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
void zebra_free_rnh(struct rnh *rnh)
{
+ struct zebra_vrf *zvrf;
+ struct route_table *table;
+
+ zebra_rnh_remove_from_routing_table(rnh);
rnh->flags |= ZEBRA_NHT_DELETED;
list_delete(&rnh->client_list);
list_delete(&rnh->zebra_pseudowire_list);
+
+ zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id);
+ table = zvrf->table[family2afi(rnh->resolved_route.family)][SAFI_UNICAST];
+
+ if (table) {
+ struct route_node *rern;
+
+ rern = route_node_match(table, &rnh->resolved_route);
+ if (rern) {
+ rib_dest_t *dest;
+
+ route_unlock_node(rern);
+
+ dest = rib_dest_from_rnode(rern);
+ listnode_delete(dest->nht, rnh);
+ }
+ }
free_state(rnh->vrf_id, rnh->state, rnh->node);
XFREE(MTYPE_RNH, rnh);
}
@@ -344,6 +434,16 @@ zebra_rnh_resolve_import_entry(struct zebra_vrf *zvrf, afi_t afi,
&& !prefix_same(&nrn->p, &rn->p))
return NULL;
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+ char buf[PREFIX_STRLEN];
+ char buf1[PREFIX_STRLEN];
+
+ zlog_debug("%s: %u:%s Resolved Import Entry to %s",
+ __PRETTY_FUNCTION__, rnh->vrf_id,
+ prefix2str(&rnh->node->p, buf, sizeof(buf)),
+ srcdest_rnode2str(rn, buf1, sizeof(buf)));
+ }
+
/* Identify appropriate route entry. */
RNODE_FOREACH_RE (rn, re) {
if (!CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)
@@ -354,6 +454,10 @@ zebra_rnh_resolve_import_entry(struct zebra_vrf *zvrf, afi_t afi,
if (re)
*prn = rn;
+
+ if (!re && IS_ZEBRA_DEBUG_NHT_DETAILED)
+ zlog_debug("\tRejected due to removed or is a bgp route");
+
return re;
}
@@ -361,9 +465,10 @@ zebra_rnh_resolve_import_entry(struct zebra_vrf *zvrf, afi_t afi,
* See if a tracked route entry for import (by BGP) has undergone any
* change, and if so, notify the client.
*/
-static void zebra_rnh_eval_import_check_entry(vrf_id_t vrfid, afi_t afi,
+static void zebra_rnh_eval_import_check_entry(struct zebra_vrf *zvrf, afi_t afi,
int force, struct route_node *nrn,
struct rnh *rnh,
+ struct route_node *prn,
struct route_entry *re)
{
int state_changed = 0;
@@ -371,25 +476,40 @@ static void zebra_rnh_eval_import_check_entry(vrf_id_t vrfid, afi_t afi,
char bufn[INET6_ADDRSTRLEN];
struct listnode *node;
+ zebra_rnh_remove_from_routing_table(rnh);
+ if (prn) {
+ prefix_copy(&rnh->resolved_route, &prn->p);
+ } else {
+ int family = rnh->resolved_route.family;
+
+ memset(&rnh->resolved_route.family, 0, sizeof(struct prefix));
+ rnh->resolved_route.family = family;
+ }
+ zebra_rnh_store_in_routing_table(rnh);
+
if (re && (rnh->state == NULL)) {
if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
state_changed = 1;
} else if (!re && (rnh->state != NULL))
state_changed = 1;
- if (compare_state(re, rnh->state))
+ if (compare_state(re, rnh->state)) {
copy_state(rnh, re, nrn);
+ state_changed = 1;
+ }
if (state_changed || force) {
if (IS_ZEBRA_DEBUG_NHT) {
prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
- zlog_debug("%u:%s: Route import check %s %s\n", vrfid,
+ zlog_debug("%u:%s: Route import check %s %s",
+ zvrf->vrf->vrf_id,
bufn, rnh->state ? "passed" : "failed",
state_changed ? "(state changed)" : "");
}
/* state changed, notify clients */
for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) {
- send_client(rnh, client, RNH_IMPORT_CHECK_TYPE, vrfid);
+ send_client(rnh, client,
+ RNH_IMPORT_CHECK_TYPE, zvrf->vrf->vrf_id);
}
}
}
@@ -412,7 +532,7 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi,
if (IS_ZEBRA_DEBUG_NHT) {
prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
if (prn && re) {
- prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN);
+ srcdest_rnode2str(prn, bufp, INET6_ADDRSTRLEN);
zlog_debug("%u:%s: NH resolved over route %s",
zvrf->vrf->vrf_id, bufn, bufp);
} else
@@ -545,19 +665,43 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
* most-specific match. Do similar logic as in zebra_rib.c
*/
while (rn) {
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+ char buf[PREFIX_STRLEN];
+ char buf1[PREFIX_STRLEN];
+
+ zlog_debug("%s: %u:%s Possible Match to %s",
+ __PRETTY_FUNCTION__, rnh->vrf_id,
+ prefix2str(&rnh->node->p, buf, sizeof(buf)),
+ srcdest_rnode2str(rn, buf1, sizeof(buf)));
+ }
+
/* Do not resolve over default route unless allowed &&
* match route to be exact if so specified
*/
if (is_default_prefix(&rn->p)
- && !rnh_resolve_via_default(rn->p.family))
+ && !rnh_resolve_via_default(rn->p.family)) {
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+ zlog_debug(
+ "\tNot allowed to resolve through default prefix");
return NULL;
+ }
/* Identify appropriate route entry. */
RNODE_FOREACH_RE (rn, re) {
- if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
+ if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) {
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+ zlog_debug(
+ "\tRoute Entry %s removed",
+ zebra_route_string(re->type));
continue;
- if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
+ }
+ if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+ zlog_debug(
+ "\tRoute Entry %s !selected",
+ zebra_route_string(re->type));
continue;
+ }
/* Just being SELECTED isn't quite enough - must
* have an installed nexthop to be useful.
@@ -567,8 +711,13 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
break;
}
- if (nexthop == NULL)
+ if (nexthop == NULL) {
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+ zlog_debug(
+ "\tRoute Entry %s no nexthops",
+ zebra_route_string(re->type));
continue;
+ }
if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) {
if ((re->type == ZEBRA_ROUTE_CONNECT)
@@ -594,10 +743,14 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
return re;
}
- if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
+ if (!CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
rn = rn->parent;
- else
+ else {
+ if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+ zlog_debug(
+ "\tNexthop must be connected, cannot recurse up");
return NULL;
+ }
}
return NULL;
@@ -629,11 +782,20 @@ static void zebra_rnh_eval_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
* the resolving route has some change (e.g., metric), there is a state
* change.
*/
- if (!prefix_same(&rnh->resolved_route, &prn->p)) {
+ zebra_rnh_remove_from_routing_table(rnh);
+ if (!prefix_same(&rnh->resolved_route, prn ? NULL : &prn->p)) {
if (prn)
prefix_copy(&rnh->resolved_route, &prn->p);
- else
+ else {
+ /*
+ * Just quickly store the family of the resolved
+ * route so that we can reset it in a second here
+ */
+ int family = rnh->resolved_route.family;
+
memset(&rnh->resolved_route, 0, sizeof(struct prefix));
+ rnh->resolved_route.family = family;
+ }
copy_state(rnh, re, nrn);
state_changed = 1;
@@ -641,6 +803,7 @@ static void zebra_rnh_eval_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
copy_state(rnh, re, nrn);
state_changed = 1;
}
+ zebra_rnh_store_in_routing_table(rnh);
if (state_changed || force) {
/* NOTE: Use the "copy" of resolving route stored in 'rnh' i.e.,
@@ -689,8 +852,8 @@ static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi,
/* Process based on type of entry. */
if (type == RNH_IMPORT_CHECK_TYPE)
- zebra_rnh_eval_import_check_entry(zvrf->vrf->vrf_id, afi, force,
- nrn, rnh, re);
+ zebra_rnh_eval_import_check_entry(zvrf, afi, force, nrn, rnh,
+ prn, re);
else
zebra_rnh_eval_nexthop_entry(zvrf, afi, force, nrn, rnh, prn,
re);
@@ -775,7 +938,7 @@ void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty,
table = get_rnh_table(vrfid, afi, type);
if (!table) {
- zlog_debug("print_rnhs: rnh table not found\n");
+ zlog_debug("print_rnhs: rnh table not found");
return;
}
@@ -790,7 +953,6 @@ void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty,
static void free_state(vrf_id_t vrf_id, struct route_entry *re,
struct route_node *rn)
{
-
if (!re)
return;
@@ -1025,7 +1187,7 @@ static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi,
ntable = get_rnh_table(vrf_id, afi, type);
if (!ntable) {
- zlog_debug("cleanup_rnh_client: rnh table not found\n");
+ zlog_debug("cleanup_rnh_client: rnh table not found");
return -1;
}
diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h
index 00ee60dc1a..7d823c7acc 100644
--- a/zebra/zebra_rnh.h
+++ b/zebra/zebra_rnh.h
@@ -25,6 +25,12 @@
#include "prefix.h"
#include "vty.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE } rnh_type_t;
+
/* Nexthop structure. */
struct rnh {
uint8_t flags;
@@ -36,6 +42,12 @@ struct rnh {
/* VRF identifier. */
vrf_id_t vrf_id;
+ afi_t afi;
+
+ rnh_type_t type;
+
+ uint32_t seqno;
+
struct route_entry *state;
struct prefix resolved_route;
struct list *client_list;
@@ -51,8 +63,6 @@ struct rnh {
int filtered[ZEBRA_ROUTE_MAX];
};
-typedef enum { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE } rnh_type_t;
-
extern int zebra_rnh_ip_default_route;
extern int zebra_rnh_ipv6_default_route;
@@ -83,4 +93,9 @@ extern void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,
extern void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty,
rnh_type_t);
extern char *rnh_str(struct rnh *rnh, char *buf, int size);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /*_ZEBRA_RNH_H */
diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h
index abd2ad78f7..6a630e1ac0 100644
--- a/zebra/zebra_routemap.h
+++ b/zebra/zebra_routemap.h
@@ -24,6 +24,10 @@
#include "lib/routemap.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern void zebra_route_map_init(void);
extern void zebra_routemap_config_write_protocol(struct vty *vty,
struct zebra_vrf *vrf);
@@ -48,4 +52,8 @@ zebra_nht_route_map_check(afi_t afi, int client_proto, const struct prefix *p,
struct zebra_vrf *zvrf, struct route_entry *,
struct nexthop *nexthop);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index cabc8be8dd..9e09cbca3f 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -164,8 +164,6 @@ static void zebra_router_free_table(struct zebra_router_table *zrt)
{
void *table_info;
- rib_close_table(zrt->table);
-
table_info = route_table_get_info(zrt->table);
route_table_finish(zrt->table);
RB_REMOVE(zebra_router_table_head, &zrouter.tables, zrt);
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h
index e5043f38ae..72b5e9b9b1 100644
--- a/zebra/zebra_router.h
+++ b/zebra/zebra_router.h
@@ -26,6 +26,10 @@
#include "zebra/zebra_ns.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* This header file contains the idea of a router and as such
* owns data that is associated with a router from zebra's
@@ -104,6 +108,11 @@ struct zebra_router {
/* Mlag information for the router */
struct zebra_mlag_info mlag_info;
+
+ /*
+ * The EVPN instance, if any
+ */
+ struct zebra_vrf *evpn_vrf;
};
extern struct zebra_router zrouter;
@@ -129,4 +138,19 @@ extern void zebra_router_sweep_route(void);
extern void zebra_router_show_table_summary(struct vty *vty);
extern uint32_t zebra_router_get_next_sequence(void);
+
+static inline vrf_id_t zebra_vrf_get_evpn_id(void)
+{
+ return zrouter.evpn_vrf ? zvrf_id(zrouter.evpn_vrf) : VRF_DEFAULT;
+}
+static inline struct zebra_vrf *zebra_vrf_get_evpn(void)
+{
+ return zrouter.evpn_vrf ? zrouter.evpn_vrf
+ : zebra_vrf_lookup_by_id(VRF_DEFAULT);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 1300ca24f3..2d721ec8a1 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -167,6 +167,11 @@ static int zebra_vrf_disable(struct vrf *vrf)
/* Remove all routes. */
for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
+ route_table_finish(zvrf->rnh_table[afi]);
+ zvrf->rnh_table[afi] = NULL;
+ route_table_finish(zvrf->import_check_table[afi]);
+ zvrf->import_check_table[afi] = NULL;
+
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
rib_close_table(zvrf->table[afi][safi]);
}
@@ -213,11 +218,6 @@ static int zebra_vrf_disable(struct vrf *vrf)
safi);
zvrf->table[afi][safi] = NULL;
}
-
- route_table_finish(zvrf->rnh_table[afi]);
- zvrf->rnh_table[afi] = NULL;
- route_table_finish(zvrf->import_check_table[afi]);
- zvrf->import_check_table[afi] = NULL;
}
return 0;
@@ -268,8 +268,10 @@ static int zebra_vrf_delete(struct vrf *vrf)
}
}
- route_table_finish(zvrf->rnh_table[afi]);
- route_table_finish(zvrf->import_check_table[afi]);
+ if (zvrf->rnh_table[afi])
+ route_table_finish(zvrf->rnh_table[afi]);
+ if (zvrf->import_check_table[afi])
+ route_table_finish(zvrf->import_check_table[afi]);
}
/* Cleanup EVPN states for vrf */
@@ -352,7 +354,12 @@ void zebra_rtable_node_cleanup(struct route_table *table,
rib_unlink(node, re);
}
- XFREE(MTYPE_RIB_DEST, node->info);
+ if (node->info) {
+ rib_dest_t *dest = node->info;
+
+ list_delete(&dest->nht);
+ XFREE(MTYPE_RIB_DEST, node->info);
+ }
}
static void zebra_rnhtable_node_cleanup(struct route_table *table,
@@ -368,10 +375,19 @@ static void zebra_rnhtable_node_cleanup(struct route_table *table,
static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
safi_t safi)
{
+ struct route_node *rn;
+ struct prefix p;
+
assert(!zvrf->table[afi][safi]);
zvrf->table[afi][safi] =
zebra_router_get_table(zvrf, zvrf->table_id, afi, safi);
+
+ memset(&p, 0, sizeof(p));
+ p.family = afi2family(afi);
+
+ rn = srcdest_rnode_get(zvrf->table[afi][safi], &p, NULL);
+ zebra_rib_create_dest(rn);
}
/* Allocate new zebra VRF. */
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index e35101d833..524c175b79 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -28,6 +28,10 @@
#include <zebra/zebra_pw.h>
#include <lib/vxlan.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* MPLS (Segment Routing) global block */
typedef struct mpls_srgb_t_ {
uint32_t start_label;
@@ -107,18 +111,18 @@ struct zebra_vrf {
#define MPLS_FLAG_SCHEDULE_LSPS (1 << 0)
/*
- * VNI hash table (for EVPN). Only in default instance.
+ * VNI hash table (for EVPN). Only in the EVPN instance.
*/
struct hash *vni_table;
/*
- * Whether EVPN is enabled or not. Only in default instance.
+ * Whether EVPN is enabled or not. Only in the EVPN instance.
*/
int advertise_all_vni;
/*
* Whether we are advertising g/w macip in EVPN or not.
- * Only in default instance.
+ * Only in the EVPN instance.
*/
int advertise_gw_macip;
@@ -203,4 +207,9 @@ extern void zebra_vrf_init(void);
extern void zebra_rtable_node_cleanup(struct route_table *table,
struct route_node *node);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* ZEBRA_VRF_H */
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index b0884f22cf..ad61842005 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -425,12 +425,6 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
json_object_boolean_true_add(json_route, "queued");
- if (re->type != ZEBRA_ROUTE_CONNECT) {
- json_object_int_add(json_route, "distance",
- re->distance);
- json_object_int_add(json_route, "metric", re->metric);
- }
-
if (re->tag)
json_object_int_add(json_route, "tag", re->tag);
@@ -1375,7 +1369,7 @@ static void vty_show_ip_route_summary(struct vty *vty,
else
rib_cnt[re->type]++;
- if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
+ if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
fib_cnt[ZEBRA_ROUTE_TOTAL]++;
if (is_ibgp)
@@ -1614,7 +1608,7 @@ DEFUN (show_vrf,
return CMD_SUCCESS;
}
-DEFUN_HIDDEN (default_vrf_vni_mapping,
+DEFUN (default_vrf_vni_mapping,
default_vrf_vni_mapping_cmd,
"vni " CMD_VNI_RANGE "[prefix-routes-only]",
"VNI corresponding to the DEFAULT VRF\n"
@@ -1644,7 +1638,7 @@ DEFUN_HIDDEN (default_vrf_vni_mapping,
return CMD_SUCCESS;
}
-DEFUN_HIDDEN (no_default_vrf_vni_mapping,
+DEFUN (no_default_vrf_vni_mapping,
no_default_vrf_vni_mapping_cmd,
"no vni " CMD_VNI_RANGE,
NO_STR
@@ -1802,7 +1796,7 @@ DEFUN (show_evpn_vni,
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_vnis(vty, zvrf, uj);
return CMD_SUCCESS;
}
@@ -1818,7 +1812,7 @@ DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd,
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_vnis_detail(vty, zvrf, uj);
return CMD_SUCCESS;
}
@@ -1837,7 +1831,7 @@ DEFUN (show_evpn_vni_vni,
bool uj = use_json(argc, argv);
vni = strtoul(argv[3]->arg, NULL, 10);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_vni(vty, zvrf, vni, uj);
return CMD_SUCCESS;
}
@@ -1981,7 +1975,7 @@ DEFUN (show_evpn_mac_vni,
bool uj = use_json(argc, argv);
vni = strtoul(argv[4]->arg, NULL, 10);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
return CMD_SUCCESS;
}
@@ -1999,7 +1993,7 @@ DEFUN (show_evpn_mac_vni_all,
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
return CMD_SUCCESS;
}
@@ -2017,7 +2011,7 @@ DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj);
return CMD_SUCCESS;
}
@@ -2043,7 +2037,7 @@ DEFUN (show_evpn_mac_vni_all_vtep,
vty_out(vty, "%% Malformed VTEP IP address\n");
return CMD_WARNING;
}
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
return CMD_SUCCESS;
@@ -2073,7 +2067,7 @@ DEFUN (show_evpn_mac_vni_mac,
vty_out(vty, "%% Malformed MAC address");
return CMD_WARNING;
}
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
return CMD_SUCCESS;
}
@@ -2102,7 +2096,7 @@ DEFUN (show_evpn_mac_vni_vtep,
return CMD_WARNING;
}
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
return CMD_SUCCESS;
}
@@ -2121,7 +2115,7 @@ DEFPY (show_evpn_mac_vni_all_dad,
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
return CMD_SUCCESS;
}
@@ -2143,7 +2137,7 @@ DEFPY (show_evpn_mac_vni_dad,
bool uj = use_json(argc, argv);
vni = strtoul(argv[4]->arg, NULL, 10);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
@@ -2166,7 +2160,7 @@ DEFPY (show_evpn_neigh_vni_dad,
bool uj = use_json(argc, argv);
vni = strtoul(argv[4]->arg, NULL, 10);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
return CMD_SUCCESS;
}
@@ -2185,7 +2179,7 @@ DEFPY (show_evpn_neigh_vni_all_dad,
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
return CMD_SUCCESS;
}
@@ -2206,7 +2200,7 @@ DEFUN (show_evpn_neigh_vni,
bool uj = use_json(argc, argv);
vni = strtoul(argv[4]->arg, NULL, 10);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
return CMD_SUCCESS;
}
@@ -2224,7 +2218,7 @@ DEFUN (show_evpn_neigh_vni_all,
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
return CMD_SUCCESS;
}
@@ -2241,7 +2235,7 @@ DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
struct zebra_vrf *zvrf;
bool uj = use_json(argc, argv);
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
return CMD_SUCCESS;
}
@@ -2269,7 +2263,7 @@ DEFUN (show_evpn_neigh_vni_neigh,
vty_out(vty, "%% Malformed Neighbor address\n");
return CMD_WARNING;
}
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
return CMD_SUCCESS;
}
@@ -2298,7 +2292,7 @@ DEFUN (show_evpn_neigh_vni_vtep,
return CMD_WARNING;
}
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
return CMD_SUCCESS;
}
@@ -2363,7 +2357,7 @@ DEFPY (clear_evpn_dup_addr,
struct ethaddr mac_addr;
int ret = CMD_SUCCESS;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
if (vni_val) {
vni = strtoul(vni_val, NULL, 10);
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 00fc230851..3a8426e772 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -324,7 +324,7 @@ static int advertise_gw_macip_enabled(zebra_vni_t *zvni)
{
struct zebra_vrf *zvrf;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
if (zvrf && zvrf->advertise_gw_macip)
return 1;
@@ -338,7 +338,7 @@ static int advertise_svi_macip_enabled(zebra_vni_t *zvni)
{
struct zebra_vrf *zvrf;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
if (zvrf && zvrf->advertise_svi_macip)
return 1;
@@ -382,6 +382,9 @@ static int zebra_vxlan_ip_inherit_dad_from_mac(struct zebra_vrf *zvrf,
SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
/* Capture Duplicate detection time */
nbr->dad_dup_detect_time = monotime(NULL);
+ /* Mark neigh inactive */
+ ZEBRA_NEIGH_SET_INACTIVE(nbr);
+
return 1;
} else if (is_old_mac_dup && !is_new_mac_dup) {
UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
@@ -704,11 +707,10 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
struct zebra_vrf *zvrf = NULL;
struct timeval detect_start_time = {0, 0};
- zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
if (!zvrf)
return;
- zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
ipaddr2str(&n->ip, buf2, sizeof(buf2));
prefix_mac2str(&n->emac, buf1, sizeof(buf1));
type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ?
@@ -1152,7 +1154,9 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
struct zebra_vrf *zvrf;
struct timeval detect_start_time = {0, 0};
- zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
+ if (!zvrf)
+ return;
vty = (struct vty *)ctxt;
prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
@@ -2076,7 +2080,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zclient_create_header(s, cmd, VRF_DEFAULT);
+ zclient_create_header(s, cmd, zebra_vrf_get_evpn_id());
stream_putl(s, vni);
stream_put(s, macaddr->octet, ETH_ALEN);
if (ip) {
@@ -2190,6 +2194,8 @@ static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
memcpy(&n->emac, mac, ETH_ALEN);
n->state = ZEBRA_NEIGH_INACTIVE;
+ n->zvni = zvni;
+ n->dad_ip_auto_recovery_timer = NULL;
/* Associate the neigh to mac */
zmac = zvni_mac_lookup(zvni, mac);
@@ -2211,6 +2217,9 @@ static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n)
if (zmac)
listnode_delete(zmac->neigh_list, n);
+ /* Cancel auto recovery */
+ THREAD_OFF(n->dad_ip_auto_recovery_timer);
+
/* Free the VNI hash entry and allocated memory. */
tmp_n = hash_release(zvni->neigh_table, n);
XFREE(MTYPE_NEIGH, tmp_n);
@@ -3191,13 +3200,14 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
return 0;
}
- ZEBRA_NEIGH_SET_ACTIVE(n);
n->loc_seq = zmac->loc_seq;
- if (!neigh_on_hold)
+ if (!neigh_on_hold) {
+ ZEBRA_NEIGH_SET_ACTIVE(n);
+
return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
n->flags, n->loc_seq);
- else {
+ } else {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("\tNeighbor on hold not sending");
}
@@ -3307,6 +3317,9 @@ static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr)
mac = hash_get(zvni->mac_table, &tmp_mac, zvni_mac_alloc);
assert(mac);
+ mac->zvni = zvni;
+ mac->dad_mac_auto_recovery_timer = NULL;
+
mac->neigh_list = list_new();
mac->neigh_list->cmp = neigh_list_cmp;
@@ -3320,6 +3333,9 @@ static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
{
zebra_mac_t *tmp_mac;
+ /* Cancel auto recovery */
+ THREAD_OFF(mac->dad_mac_auto_recovery_timer);
+
list_delete(&mac->neigh_list);
/* Free the VNI hash entry and allocated memory. */
@@ -3817,7 +3833,7 @@ static zebra_vni_t *zvni_lookup(vni_t vni)
zebra_vni_t tmp_vni;
zebra_vni_t *zvni = NULL;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
assert(zvrf);
memset(&tmp_vni, 0, sizeof(zebra_vni_t));
tmp_vni.vni = vni;
@@ -3835,7 +3851,7 @@ static zebra_vni_t *zvni_add(vni_t vni)
zebra_vni_t tmp_zvni;
zebra_vni_t *zvni = NULL;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
assert(zvrf);
memset(&tmp_zvni, 0, sizeof(zebra_vni_t));
tmp_zvni.vni = vni;
@@ -3861,7 +3877,7 @@ static int zvni_del(zebra_vni_t *zvni)
struct zebra_vrf *zvrf;
zebra_vni_t *tmp_zvni;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
assert(zvrf);
zvni->vxlan_if = NULL;
@@ -3896,7 +3912,7 @@ static int zvni_send_add_to_client(zebra_vni_t *zvni)
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zclient_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
+ zclient_create_header(s, ZEBRA_VNI_ADD, zebra_vrf_get_evpn_id());
stream_putl(s, zvni->vni);
stream_put_in_addr(s, &zvni->local_vtep_ip);
stream_put(s, &zvni->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */
@@ -3930,7 +3946,7 @@ static int zvni_send_del_to_client(vni_t vni)
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
stream_reset(s);
- zclient_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT);
+ zclient_create_header(s, ZEBRA_VNI_DEL, zebra_vrf_get_evpn_id());
stream_putl(s, vni);
/* Write packet size. */
@@ -6940,7 +6956,7 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
if (!is_evpn_enabled())
return;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
+ zvrf = zebra_vrf_get_evpn();
if (!zvrf)
return;
@@ -7782,9 +7798,9 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
return;
}
- if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_debug("Recv MACIP DEL for non-default VRF %u",
- zvrf_id(zvrf));
+ if (!EVPN_ENABLED(zvrf)) {
+ zlog_debug("Recv MACIP DEL for non-EVPN VRF %u",
+ zvrf_id(zvrf));
return;
}
@@ -7866,9 +7882,9 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
return;
}
- if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_debug("Recv MACIP ADD for non-default VRF %u",
- zvrf_id(zvrf));
+ if (!EVPN_ENABLED(zvrf)) {
+ zlog_debug("Recv MACIP ADD for non-EVPN VRF %u",
+ zvrf_id(zvrf));
return;
}
@@ -8602,10 +8618,10 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
int add)
{
zebra_l3vni_t *zl3vni = NULL;
- struct zebra_vrf *zvrf_default = NULL;
+ struct zebra_vrf *zvrf_evpn = NULL;
- zvrf_default = zebra_vrf_lookup_by_id(VRF_DEFAULT);
- if (!zvrf_default)
+ zvrf_evpn = zebra_vrf_get_evpn();
+ if (!zvrf_evpn)
return -1;
if (IS_ZEBRA_DEBUG_VXLAN)
@@ -8659,7 +8675,7 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
/* formulate l2vni list */
- hash_iterate(zvrf_default->vni_table, zvni_add_to_l3vni_list,
+ hash_iterate(zvrf_evpn->vni_table, zvni_add_to_l3vni_list,
zl3vni);
if (is_l3vni_oper_up(zl3vni))
@@ -8754,8 +8770,8 @@ void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS)
struct stream *s;
enum vxlan_flood_control flood_ctrl;
- if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_err("EVPN flood control for non-default VRF %u",
+ if (!EVPN_ENABLED(zvrf)) {
+ zlog_err("EVPN flood control for non-EVPN VRF %u",
zvrf_id(zvrf));
return;
}
@@ -8794,9 +8810,9 @@ void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS)
zebra_vni_t *zvni = NULL;
struct interface *ifp = NULL;
- if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
- zvrf_id(zvrf));
+ if (!EVPN_ENABLED(zvrf)) {
+ zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
+ zvrf_id(zvrf));
return;
}
@@ -8893,9 +8909,9 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
struct zebra_l2info_vxlan zl2_info;
struct interface *vlan_if = NULL;
- if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
- zvrf_id(zvrf));
+ if (!EVPN_ENABLED(zvrf)) {
+ zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
+ zvrf_id(zvrf));
return;
}
@@ -8956,8 +8972,8 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
zebra_vni_t *zvni = NULL;
struct interface *ifp = NULL;
- if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_debug("EVPN GW-MACIP Adv for non-default VRF %u",
+ if (!EVPN_ENABLED(zvrf)) {
+ zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
zvrf_id(zvrf));
return;
}
@@ -9063,18 +9079,18 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
int advertise = 0;
enum vxlan_flood_control flood_ctrl;
- if (zvrf_id(zvrf) != VRF_DEFAULT) {
- zlog_debug("EVPN VNI Adv for non-default VRF %u",
- zvrf_id(zvrf));
+ /* Mismatch between EVPN VRF and current VRF (should be prevented by
+ * bgpd's cli) */
+ if (is_evpn_enabled() && !EVPN_ENABLED(zvrf))
return;
- }
s = msg;
STREAM_GETC(s, advertise);
STREAM_GETC(s, flood_ctrl);
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("EVPN VNI Adv %s, currently %s, flood control %u",
+ zlog_debug("EVPN VRF %s(%u) VNI Adv %s, currently %s, flood control %u",
+ zvrf_name(zvrf), zvrf_id(zvrf),
advertise ? "enabled" : "disabled",
is_evpn_enabled() ? "enabled" : "disabled",
flood_ctrl);
@@ -9083,7 +9099,9 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
return;
zvrf->advertise_all_vni = advertise;
- if (is_evpn_enabled()) {
+ if (EVPN_ENABLED(zvrf)) {
+ zrouter.evpn_vrf = zvrf;
+
/* Note BUM handling */
zvrf->vxlan_flood_ctrl = flood_ctrl;
@@ -9107,6 +9125,9 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
/* cleanup all l3vnis */
hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL);
+
+ /* Mark as "no EVPN VRF" */
+ zrouter.evpn_vrf = NULL;
}
stream_failure:
@@ -9147,6 +9168,7 @@ void zebra_vxlan_init(void)
{
zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
"Zebra VRF L3 VNI table");
+ zrouter.evpn_vrf = NULL;
}
/* free l3vni table */
@@ -9193,8 +9215,8 @@ static int zebra_vxlan_dad_ip_auto_recovery_exp(struct thread *t)
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("%s: duplicate addr MAC %s IP %s flags 0x%x learn count %u vni %u auto recovery expired",
__PRETTY_FUNCTION__,
- prefix_mac2str(&nbr->emac, buf1, sizeof(buf1)),
- ipaddr2str(&nbr->ip, buf2, sizeof(buf2)),
+ prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)),
+ ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
nbr->flags,
nbr->dad_count, zvni->vni);
@@ -9204,6 +9226,7 @@ static int zebra_vxlan_dad_ip_auto_recovery_exp(struct thread *t)
nbr->detect_start_time.tv_usec = 0;
nbr->dad_dup_detect_time = 0;
nbr->dad_ip_auto_recovery_timer = NULL;
+ ZEBRA_NEIGH_SET_ACTIVE(nbr);
/* Send to BGP */
if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) {
diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h
index 2cf21ff90b..2ff92970d7 100644
--- a/zebra/zebra_vxlan.h
+++ b/zebra/zebra_vxlan.h
@@ -25,6 +25,7 @@
#define _ZEBRA_VXLAN_H
#include <zebra.h>
+#include <zebra/zebra_router.h>
#include "linklist.h"
#include "if.h"
@@ -35,19 +36,23 @@
#include "zebra/zebra_vrf.h"
#include "zebra/zserv.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Is EVPN enabled? */
#define EVPN_ENABLED(zvrf) (zvrf)->advertise_all_vni
static inline int is_evpn_enabled(void)
{
struct zebra_vrf *zvrf = NULL;
- zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
- return zvrf ? zvrf->advertise_all_vni : 0;
+ zvrf = zebra_vrf_get_evpn();
+ return zvrf ? EVPN_ENABLED(zvrf) : 0;
}
static inline int
is_vxlan_flooding_head_end(void)
{
- struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
+ struct zebra_vrf *zvrf = zebra_vrf_get_evpn();
if (!zvrf)
return 0;
@@ -206,4 +211,8 @@ extern int zebra_vxlan_clear_dup_detect_vni(struct vty *vty,
struct zebra_vrf *zvrf,
vni_t vni);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_VXLAN_H */
diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h
index c36d156359..5081c08d19 100644
--- a/zebra/zebra_vxlan_private.h
+++ b/zebra/zebra_vxlan_private.h
@@ -26,12 +26,14 @@
#include <zebra.h>
-#include <zebra.h>
-
#include "if.h"
#include "linklist.h"
#include "zebra_vxlan.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define ERR_STR_SZ 256
/* definitions */
@@ -421,4 +423,8 @@ struct nh_walk_ctx {
struct json_object *json;
};
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_VXLAN_PRIVATE_H */
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 6532491cef..f5bb3aabb7 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -773,6 +773,18 @@ static int zserv_accept(struct thread *thread)
return 0;
}
+void zserv_close(void)
+{
+ /*
+ * On shutdown, let's close the socket down
+ * so that long running processes of killing the
+ * routing table doesn't leave us in a bad
+ * state where a client tries to reconnect
+ */
+ close(zsock);
+ zsock = -1;
+}
+
void zserv_start(char *path)
{
int ret;
diff --git a/zebra/zserv.h b/zebra/zserv.h
index ac016e65f3..86863d961c 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -40,6 +40,10 @@
#include "zebra/zebra_vrf.h" /* for zebra_vrf */
/* clang-format on */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Default port information. */
#define ZEBRA_VTY_PORT 2601
@@ -180,6 +184,13 @@ extern unsigned int multipath_num;
extern void zserv_init(void);
/*
+ * Stop the Zebra API server.
+ *
+ * closes the socket
+ */
+extern void zserv_close(void);
+
+/*
* Start Zebra API server.
*
* Allocates resources, creates the server socket and begins listening on the
@@ -234,4 +245,8 @@ extern void zserv_read_file(char *input);
/* TODO */
int zebra_finalize(struct thread *event);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _ZEBRA_ZEBRA_H */