diff options
153 files changed, 4432 insertions, 4182 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..cedca17729 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,43 @@ +### How to submit an issue +Please use this text as a template and replace text in the sections or remove +the entire section if it does not apply to your issue. For example in case of +a question or feature request, just a description with some example is probably +fine. Also remember to use GitHub Flavored Markdown properly, especially if +posting output or code listings. + +### Things you may try first +(put "x" in "[ ]" if you already tried following) +* [ ] Did you check if this is a duplicate issue? +* [ ] Did you test it on the latest FRRouting/frr master branch? + +**Related Issue:** +[fill here if applicable] + +### Description +[Description of the bug or feature] + +### Steps to Reproduce +1. [First Step] +2. [Second Step] +3. [and so on...] + +**Expected behavior:** +[What you expected to happen] + +**Actual behavior:** +[What actually happened] + +### Components +[bgpd, build, doc, isisd, ospfd, etc.] + +### Versions +* OS: [name] [version] +* Kernel: [Linux/BSD] [version] +* FRR: [version] + +### Attachments +[Attach if applicable. For example log-files, log-lines. etc. etc.] + +You're also welcomed to provide us with any other data you think may be useful. + +Thanks! diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..0a8aa03c8d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,12 @@ +### Summary +[fill here] + +### Related Issue +[fill here if applicable] + +### Components +[bgpd, build, doc, ripd, ospfd, eigrpd, isisd, etc. etc.] + +Always remember to follow proper coding style etc. as +described in the FRRouting Dev Guide. +http://docs.frrouting.org/projects/dev-guide/en/latest/workflow.html diff --git a/Makefile.am b/Makefile.am index 3e268f703d..b9003b8358 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,6 +8,62 @@ AM_CPPFLAGS += -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/lib \ DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE) LIBCAP = @LIBCAP@ +# these two targets are provided to easily grab autoconf/Makefile variables +# you can use either: +# eval `make VARFD=3 shvar-CFLAGS 3>&1 1>&2` +# CFLAGS="`make VARFD=3 var-CFLAGS 3>&1 1>&2`" +# where the former can be used to set several variables at once. Note the +# fd redirections -- this is to prevent garbage from make rebuilding other +# targets from causing issues. +.PHONY: shvar-% var-% +VARFD ?= 1 +shvar-%: + @echo "$*=\"$($*)\"" >&$(VARFD) +var-%: + @echo "$($*)" >&$(VARFD) + +# overwriting these vars breaks cross-compilation. let's be helpful and warn. +# +# note: "#AUTODERP# " will be removed from Makefile by configure. These are +# GNU make directives & automake will f*ck them up by trying to process them +# as automake directives. +# +#AUTODERP# null= +#AUTODERP# SPACE=$(null) $(null) +#AUTODERP# mkcheck_CC = $(findstring $(SPACE)CC=, $(SPACE)$(MAKEOVERRIDES)) +#AUTODERP# mkcheck_CFLAGS = $(findstring $(SPACE)CFLAGS=, $(SPACE)$(MAKEOVERRIDES)) +#AUTODERP# mkcheck_CPPFLAGS = $(findstring $(SPACE)CPPFLAGS=,$(SPACE)$(MAKEOVERRIDES)) +#AUTODERP# mkcheck_CCLD = $(findstring $(SPACE)CCLD=, $(SPACE)$(MAKEOVERRIDES)) +#AUTODERP# mkcheck_LD = $(findstring $(SPACE)LD=, $(SPACE)$(MAKEOVERRIDES)) +#AUTODERP# mkcheck_LDFLAGS = $(findstring $(SPACE)LDFLAGS=, $(SPACE)$(MAKEOVERRIDES)) +#AUTODERP# # +#AUTODERP# ifneq ($(mkcheck_CC),) +#AUTODERP# $(warning WARNING: you have overwritten the "CC" variable on the make command line.) +#AUTODERP# endif +#AUTODERP# ifneq ($(mkcheck_CFLAGS),) +#AUTODERP# $(warning WARNING: you have overwritten the "CFLAGS" variable on the make command line.) +#AUTODERP# endif +#AUTODERP# ifneq ($(mkcheck_CPPFLAGS),) +#AUTODERP# $(warning WARNING: you have overwritten the "CPPFLAGS" variable on the make command line.) +#AUTODERP# endif +#AUTODERP# ifneq ($(mkcheck_CCLD),) +#AUTODERP# $(warning WARNING: you have overwritten the "CCLD" variable on the make command line.) +#AUTODERP# endif +#AUTODERP# ifneq ($(mkcheck_LD),) +#AUTODERP# $(warning WARNING: you have overwritten the "LD" variable on the make command line.) +#AUTODERP# endif +#AUTODERP# ifneq ($(mkcheck_LDFLAGS),) +#AUTODERP# $(warning WARNING: you have overwritten the "LDFLAGS" variable on the make command line.) +#AUTODERP# endif +#AUTODERP# # +#AUTODERP# ifneq ($(mkcheck_CC)$(mkcheck_CFLAGS)$(mkcheck_CPPFLAGS)$(mkcheck_CCLD)$(mkcheck_LD)$(mkcheck_LDFLAGS),) +#AUTODERP# $(warning ------) +#AUTODERP# $(warning While overwriting these variables works most of the time, it is not recommended and can cause confusing build errors.) +#AUTODERP# $(warning This is especially problematic when cross-compiling, since tools that run on the build system during the build process will not be compiled correctly.) +#AUTODERP# $(warning All of these variables should be supplied to 'configure', and they will be remembered and correctly applied during 'make'.) +#AUTODERP# $(warning ------) +#AUTODERP# endif + EXTRA_DIST = BUILT_SOURCES = CLEANFILES = @@ -20,11 +76,13 @@ sbin_SCRIPTS = noinst_PROGRAMS = noinst_HEADERS = noinst_LIBRARIES = +nodist_noinst_DATA = lib_LTLIBRARIES = module_LTLIBRARIES = pkginclude_HEADERS = nodist_pkginclude_HEADERS = dist_examples_DATA = +man_MANS = ## libtool, the self-made GNU scourge ## ... this should fix relinking @@ -34,6 +92,10 @@ $(AUTOMAKE_DUMMY)install-moduleLTLIBRARIES: install-libLTLIBRARIES $(AUTOMAKE_DUMMY)install-binPROGRAMS: install-libLTLIBRARIES $(AUTOMAKE_DUMMY)install-sbinPROGRAMS: install-libLTLIBRARIES +include doc/subdir.am +include doc/user/subdir.am +include doc/manpages/subdir.am +include doc/developer/subdir.am include include/subdir.am include lib/subdir.am include zebra/subdir.am @@ -41,6 +103,8 @@ include watchfrr/subdir.am include qpb/subdir.am include fpm/subdir.am include tools/subdir.am +include debianpkg/subdir.am +include solaris/subdir.am include ripd/subdir.am include ripngd/subdir.am @@ -60,14 +124,13 @@ include bfdd/subdir.am SUBDIRS = . @LIBRFP@ @RFPTEST@ \ @BGPD@ \ - @VTYSH@ @DOC@ \ - @SOLARIS@ tests + @VTYSH@ \ + tests DIST_SUBDIRS = . bgpd \ - vtysh doc tests \ - solaris bgpd/rfp-example/librfp \ + vtysh tests \ + bgpd/rfp-example/librfp \ bgpd/rfp-example/rfptest \ - debianpkg \ # end if PKGSRC @@ -108,6 +171,11 @@ EXTRA_DIST += \ \ vtysh/Makefile.am \ vtysh/Makefile.in \ + \ + doc/Makefile \ + doc/developer/Makefile \ + doc/manpages/Makefile \ + doc/user/Makefile \ # end ACLOCAL_AMFLAGS = -I m4 diff --git a/bfdd/bfd.c b/bfdd/bfd.c index b3253a14d7..cf7c027db5 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -78,7 +78,7 @@ struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc) } else { memset(&shop, 0, sizeof(shop)); shop.peer = bpc->bpc_peer; - if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif) + if (bpc->bpc_has_localif) strlcpy(shop.port_name, bpc->bpc_localif, sizeof(shop.port_name)); @@ -311,33 +311,6 @@ struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, char *port_name, return l_bfd; } -#if 0 /* TODO VxLAN Support */ -static void -_update_vxlan_sess_parms(struct bfd_session *bfd, bfd_sess_parms *sess_parms) -{ - struct bfd_session_vxlan_info *vxlan_info = &bfd->vxlan_info; - bfd_parms_list *parms = &sess_parms->parms; - - vxlan_info->vnid = parms->vnid; - vxlan_info->check_tnl_key = parms->check_tnl_key; - vxlan_info->forwarding_if_rx = parms->forwarding_if_rx; - vxlan_info->cpath_down = parms->cpath_down; - vxlan_info->decay_min_rx = parms->decay_min_rx; - - inet_aton(parms->local_dst_ip, &vxlan_info->local_dst_ip); - inet_aton(parms->remote_dst_ip, &vxlan_info->peer_dst_ip); - - memcpy(vxlan_info->local_dst_mac, parms->local_dst_mac, ETH_ALEN); - memcpy(vxlan_info->peer_dst_mac, parms->remote_dst_mac, ETH_ALEN); - - /* The interface may change for Vxlan BFD sessions, so update - * the local mac and ifindex - */ - bfd->ifindex = sess_parms->ifindex; - memcpy(bfd->local_mac, sess_parms->local_mac, sizeof(bfd->local_mac)); -} -#endif /* VxLAN support */ - int bfd_xmt_cb(struct thread *t) { struct bfd_session *bs = THREAD_ARG(t); @@ -364,7 +337,7 @@ int bfd_recvtimer_cb(struct thread *t) switch (bs->ses_state) { case PTM_BFD_INIT: case PTM_BFD_UP: - ptm_bfd_ses_dn(bs, BFD_DIAGDETECTTIME); + ptm_bfd_ses_dn(bs, BD_CONTROL_EXPIRED); bfd_recvtimer_update(bs); break; @@ -387,7 +360,7 @@ int bfd_echo_recvtimer_cb(struct thread *t) switch (bs->ses_state) { case PTM_BFD_INIT: case PTM_BFD_UP: - ptm_bfd_ses_dn(bs, BFD_DIAGDETECTTIME); + ptm_bfd_ses_dn(bs, BD_ECHO_FAILED); break; } @@ -535,8 +508,6 @@ static int bfd_session_update(struct bfd_session *bs, struct bfd_peer_cfg *bpc) _bfd_session_update(bs, bpc); - /* TODO add VxLAN support. */ - control_notify_config(BCM_NOTIFY_CONFIG_UPDATE, bs); return 0; @@ -606,9 +577,6 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc) ptm_bfd_fetch_local_mac(bpc->bpc_localif, bfd->local_mac); } - if (bpc->bpc_has_vxlan) - BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN); - if (bpc->bpc_ipv4 == false) { BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6); @@ -644,30 +612,13 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc) bfd_mhop_insert(bfd); } else { bfd->shop.peer = bpc->bpc_peer; - if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif) + if (bpc->bpc_has_localif) strlcpy(bfd->shop.port_name, bpc->bpc_localif, sizeof(bfd->shop.port_name)); bfd_shop_insert(bfd); } - if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN)) { - static uint8_t bfd_def_vxlan_dmac[] = {0x00, 0x23, 0x20, - 0x00, 0x00, 0x01}; - memcpy(bfd->peer_mac, bfd_def_vxlan_dmac, - sizeof(bfd_def_vxlan_dmac)); - } -#if 0 /* TODO */ - else if (event->rmac) { - if (sscanf(event->rmac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &bfd->peer_mac[0], &bfd->peer_mac[1], &bfd->peer_mac[2], - &bfd->peer_mac[3], &bfd->peer_mac[4], &bfd->peer_mac[5]) - != 6) - DLOG("%s: Assigning remote mac = %s", __func__, - event->rmac); - } -#endif - /* * XXX: session update triggers echo start, so we must have our * discriminator ID set first. diff --git a/bfdd/bfd.h b/bfdd/bfd.h index d665448abf..3a58a8d53c 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -105,9 +105,6 @@ struct bfd_echo_pkt { #define BFD_CBIT 0x08 #define BFD_ABIT 0x04 #define BFD_DEMANDBIT 0x02 -#define BFD_DIAGNEIGHDOWN 3 -#define BFD_DIAGDETECTTIME 1 -#define BFD_DIAGADMINDOWN 7 #define BFD_SETDEMANDBIT(flags, val) \ { \ if ((val)) \ @@ -133,18 +130,27 @@ struct bfd_echo_pkt { #define BFD_GETSTATE(flags) ((flags >> 6) & 0x3) #define BFD_ECHO_VERSION 1 #define BFD_ECHO_PKT_LEN sizeof(struct bfd_echo_pkt) -#define BFD_CTRL_PKT_LEN sizeof(struct bfd_pkt) -#define IP_HDR_LEN 20 -#define UDP_HDR_LEN 8 -#define ETH_HDR_LEN 14 -#define VXLAN_HDR_LEN 8 -#define HEADERS_MIN_LEN (ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN) -#define BFD_ECHO_PKT_TOT_LEN \ - ((int)(ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN + BFD_ECHO_PKT_LEN)) -#define BFD_VXLAN_PKT_TOT_LEN \ - ((int)(VXLAN_HDR_LEN + ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN \ - + BFD_CTRL_PKT_LEN)) -#define BFD_RX_BUF_LEN 160 + +enum bfd_diagnosticis { + BD_OK = 0, + /* Control Detection Time Expired. */ + BD_CONTROL_EXPIRED = 1, + /* Echo Function Failed. */ + BD_ECHO_FAILED = 2, + /* Neighbor Signaled Session Down. */ + BD_NEIGHBOR_DOWN = 3, + /* Forwarding Plane Reset. */ + BD_FORWARDING_RESET = 4, + /* Path Down. */ + BD_PATH_DOWN = 5, + /* Concatenated Path Down. */ + BD_CONCATPATH_DOWN = 6, + /* Administratively Down. */ + BD_ADMIN_DOWN = 7, + /* Reverse Concatenated Path Down. */ + BD_REVCONCATPATH_DOWN = 8, + /* 9..31: reserved. */ +}; /* BFD session flags */ enum bfd_session_flags { @@ -154,9 +160,6 @@ enum bfd_session_flags { * actively */ BFD_SESS_FLAG_MH = 1 << 2, /* BFD Multi-hop session */ - BFD_SESS_FLAG_VXLAN = 1 << 3, /* BFD Multi-hop session which is - * used to monitor vxlan tunnel - */ BFD_SESS_FLAG_IPV6 = 1 << 4, /* BFD IPv6 session */ BFD_SESS_FLAG_SEND_EVT_ACTIVE = 1 << 5, /* send event timer active */ BFD_SESS_FLAG_SEND_EVT_IGNORE = 1 << 6, /* ignore send event when timer @@ -191,18 +194,6 @@ struct bfd_session_stats { uint64_t znotification; }; -struct bfd_session_vxlan_info { - uint32_t vnid; - uint32_t decay_min_rx; - uint8_t forwarding_if_rx; - uint8_t cpath_down; - uint8_t check_tnl_key; - uint8_t local_dst_mac[ETHERNET_ADDRESS_LENGTH]; - uint8_t peer_dst_mac[ETHERNET_ADDRESS_LENGTH]; - struct in_addr local_dst_ip; - struct in_addr peer_dst_ip; -}; - /* bfd_session shortcut label forwarding. */ struct peer_label; @@ -249,16 +240,11 @@ struct bfd_session { int ifindex; uint8_t local_mac[ETHERNET_ADDRESS_LENGTH]; uint8_t peer_mac[ETHERNET_ADDRESS_LENGTH]; - uint16_t ip_id; /* BFD session flags */ enum bfd_session_flags flags; - uint8_t echo_pkt[BFD_ECHO_PKT_TOT_LEN]; /* Save the Echo Packet - * which will be transmitted - */ struct bfd_session_stats stats; - struct bfd_session_vxlan_info vxlan_info; struct timeval uptime; /* last up time */ struct timeval downtime; /* last down time */ @@ -407,7 +393,7 @@ struct bfd_global { int bg_shop6; int bg_mhop6; int bg_echo; - int bg_vxlan; + int bg_echov6; struct thread *bg_ev[6]; int bg_csock; @@ -473,10 +459,10 @@ void log_fatal(const char *fmt, ...); * * Contains the code related with receiving/seding, packing/unpacking BFD data. */ -int bp_set_ttlv6(int sd); -int bp_set_ttl(int sd); -int bp_set_tosv6(int sd); -int bp_set_tos(int sd); +int bp_set_ttlv6(int sd, uint8_t value); +int bp_set_ttl(int sd, uint8_t value); +int bp_set_tosv6(int sd, uint8_t value); +int bp_set_tos(int sd, uint8_t value); int bp_bind_dev(int sd, const char *dev); int bp_udp_shop(void); @@ -485,14 +471,14 @@ int bp_udp6_shop(void); int bp_udp6_mhop(void); int bp_peer_socket(struct bfd_peer_cfg *bpc); int bp_peer_socketv6(struct bfd_peer_cfg *bpc); +int bp_echo_socket(void); +int bp_echov6_socket(void); void ptm_bfd_snd(struct bfd_session *bfd, int fbit); void ptm_bfd_echo_snd(struct bfd_session *bfd); int bfd_recv_cb(struct thread *t); -uint16_t checksum(uint16_t *buf, int len); - /* * event.c @@ -602,30 +588,13 @@ int ptm_bfd_notify(struct bfd_session *bs); /* * OS compatibility functions. */ -struct udp_psuedo_header { - uint32_t saddr; - uint32_t daddr; - uint8_t reserved; - uint8_t protocol; - uint16_t len; -}; - -#define UDP_PSUEDO_HDR_LEN sizeof(struct udp_psuedo_header) - #if defined(BFD_LINUX) || defined(BFD_BSD) int ptm_bfd_fetch_ifindex(const char *ifname); void ptm_bfd_fetch_local_mac(const char *ifname, uint8_t *mac); void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen); -int ptm_bfd_echo_sock_init(void); -int ptm_bfd_vxlan_sock_init(void); #endif /* BFD_LINUX || BFD_BSD */ -#ifdef BFD_LINUX -uint16_t udp4_checksum(struct iphdr *iph, uint8_t *buf, int len); -#endif /* BFD_LINUX */ - #ifdef BFD_BSD -uint16_t udp4_checksum(struct ip *ip, uint8_t *buf, int len); ssize_t bsd_echo_sock_read(int sd, uint8_t *buf, ssize_t *buflen, struct sockaddr_storage *ss, socklen_t *sslen, uint8_t *ttl, uint32_t *id); diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c index 543181a12a..4bdfb314e2 100644 --- a/bfdd/bfd_packet.c +++ b/bfdd/bfd_packet.c @@ -37,74 +37,26 @@ #include "bfd.h" -/* - * Definitions - */ - -/* iov for BFD control frames */ -#define CMSG_HDR_LEN sizeof(struct cmsghdr) -#define CMSG_TTL_LEN (CMSG_HDR_LEN + sizeof(uint32_t)) -#define CMSG_IN_PKT_INFO_LEN (CMSG_HDR_LEN + sizeof(struct in_pktinfo) + 4) -#define CMSG_IN6_PKT_INFO_LEN \ - (CMSG_HDR_LEN + sizeof(struct in6_addr) + sizeof(int) + 4) - -struct bfd_raw_echo_pkt { -#ifdef BFD_LINUX - struct iphdr ip; -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - struct ip ip; -#endif /* BFD_BSD */ - struct udphdr udp; - struct bfd_echo_pkt data; -}; - -#if 0 /* TODO: VxLAN support. */ -struct bfd_raw_ctrl_pkt { - struct iphdr ip; - struct udphdr udp; - struct bfd_pkt data; -}; -#endif - -struct vxlan_hdr { - uint32_t flags; - uint32_t vnid; -}; - -#define IP_ECHO_PKT_LEN (IP_HDR_LEN + UDP_HDR_LEN + BFD_ECHO_PKT_LEN) -#define UDP_ECHO_PKT_LEN (UDP_HDR_LEN + BFD_ECHO_PKT_LEN) -#define IP_CTRL_PKT_LEN (IP_HDR_LEN + UDP_HDR_LEN + BFD_PKT_LEN) -#define UDP_CTRL_PKT_LEN (UDP_HDR_LEN + BFD_PKT_LEN) - -static uint8_t msgbuf[BFD_PKT_LEN]; - -static int ttlval = BFD_TTL_VAL; -static int tosval = BFD_TOS_VAL; -static int rcvttl = BFD_RCV_TTL_VAL; /* * Prototypes */ -static uint16_t ptm_bfd_gen_IP_ID(struct bfd_session *bfd); -static void ptm_bfd_echo_pkt_create(struct bfd_session *bfd); -static int ptm_bfd_echo_loopback(uint8_t *pkt, int pkt_len, struct sockaddr *ss, - socklen_t sslen); -static void ptm_bfd_vxlan_pkt_snd(struct bfd_session *bfd, int fbit); static int ptm_bfd_process_echo_pkt(int s); -static bool -ptm_bfd_validate_vxlan_pkt(struct bfd_session *bfd, - struct bfd_session_vxlan_info *vxlan_info); +int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data, + size_t datalen); static void bfd_sd_reschedule(int sd); -static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, - char *vrfname, size_t vrfnamelen, - struct sockaddr_any *local, - struct sockaddr_any *peer); -static ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, - char *vrfname, size_t vrfnamelen, - struct sockaddr_any *local, - struct sockaddr_any *peer); +ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, + char *port, size_t portlen, char *vrfname, + size_t vrfnamelen, struct sockaddr_any *local, + struct sockaddr_any *peer); +ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, + char *port, size_t portlen, char *vrfname, + size_t vrfnamelen, struct sockaddr_any *local, + struct sockaddr_any *peer); +int bp_udp_send(int sd, uint8_t ttl, uint8_t *data, size_t datalen, + struct sockaddr *to, socklen_t tolen); +int bp_bfd_echo_in(int sd, uint8_t *ttl, uint32_t *my_discr); /* socket related prototypes */ static void bp_set_ipopts(int sd); @@ -116,68 +68,17 @@ static void bp_bind_ipv6(int sd, uint16_t port); /* * Functions */ -uint16_t checksum(uint16_t *buf, int len) -{ - int nbytes = len; - int sum = 0; - uint16_t csum = 0; - int size = sizeof(uint16_t); - - while (nbytes > 1) { - sum += *buf++; - nbytes -= size; - } - - if (nbytes == 1) { - *(uint8_t *)(&csum) = *(uint8_t *)buf; - sum += csum; - } - - sum = (sum >> 16) + (sum & 0xFFFF); - sum += (sum >> 16); - csum = ~sum; - return csum; -} - -static uint16_t ptm_bfd_gen_IP_ID(struct bfd_session *bfd) -{ - return (++bfd->ip_id); -} - -static int _ptm_bfd_send(struct bfd_session *bs, bool use_layer2, - uint16_t *port, const void *data, size_t datalen) +int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data, + size_t datalen) { struct sockaddr *sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; -#ifdef BFD_LINUX - struct sockaddr_ll dll; -#endif /* BFD_LINUX */ socklen_t slen; ssize_t rv; int sd = -1; - if (use_layer2) { -#ifdef BFD_LINUX - memset(&dll, 0, sizeof(dll)); - dll.sll_family = AF_PACKET; - dll.sll_protocol = htons(ETH_P_IP); - memcpy(dll.sll_addr, bs->peer_mac, ETHERNET_ADDRESS_LENGTH); - dll.sll_halen = htons(ETHERNET_ADDRESS_LENGTH); - dll.sll_ifindex = bs->ifindex; - - sd = bglobal.bg_echo; - sa = (struct sockaddr *)&dll; - slen = sizeof(dll); -#else - /* - * TODO: implement layer 2 send for *BSDs. This is - * needed for VxLAN. - */ - log_warning("packet-send: not implemented"); - return -1; -#endif - } else if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) { + if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) { memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_addr = bs->shop.peer.sa_sin6.sin6_addr; @@ -219,332 +120,63 @@ static int _ptm_bfd_send(struct bfd_session *bs, bool use_layer2, return 0; } -static void ptm_bfd_echo_pkt_create(struct bfd_session *bfd) -{ - struct bfd_raw_echo_pkt ep; - uint8_t *pkt = bfd->echo_pkt; - - memset(&ep, 0, sizeof(ep)); - memset(bfd->echo_pkt, 0, sizeof(bfd->echo_pkt)); - - /* Construct ethernet header information */ - memcpy(pkt, bfd->peer_mac, ETHERNET_ADDRESS_LENGTH); - pkt = pkt + ETHERNET_ADDRESS_LENGTH; - memcpy(pkt, bfd->local_mac, ETHERNET_ADDRESS_LENGTH); - pkt = pkt + ETHERNET_ADDRESS_LENGTH; -#ifdef BFD_LINUX - pkt[0] = ETH_P_IP / 256; - pkt[1] = ETH_P_IP % 256; -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - pkt[0] = ETHERTYPE_IP / 256; - pkt[1] = ETHERTYPE_IP % 256; -#endif /* BFD_BSD */ - pkt += 2; - - /* Construct IP header information */ -#ifdef BFD_LINUX - ep.ip.version = 4; - ep.ip.ihl = 5; - ep.ip.tos = 0; - ep.ip.tot_len = htons(IP_ECHO_PKT_LEN); - ep.ip.id = htons(ptm_bfd_gen_IP_ID(bfd)); - ep.ip.frag_off = 0; - ep.ip.ttl = BFD_TTL_VAL; - ep.ip.protocol = IPPROTO_UDP; - ep.ip.saddr = bfd->local_ip.sa_sin.sin_addr.s_addr; - ep.ip.daddr = bfd->shop.peer.sa_sin.sin_addr.s_addr; - ep.ip.check = checksum((uint16_t *)&ep.ip, IP_HDR_LEN); -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - ep.ip.ip_v = 4; - ep.ip.ip_hl = 5; - ep.ip.ip_tos = 0; - ep.ip.ip_len = htons(IP_ECHO_PKT_LEN); - ep.ip.ip_id = htons(ptm_bfd_gen_IP_ID(bfd)); - ep.ip.ip_off = 0; - ep.ip.ip_ttl = BFD_TTL_VAL; - ep.ip.ip_p = IPPROTO_UDP; - ep.ip.ip_src = bfd->local_ip.sa_sin.sin_addr; - ep.ip.ip_dst = bfd->shop.peer.sa_sin.sin_addr; - ep.ip.ip_sum = checksum((uint16_t *)&ep.ip, IP_HDR_LEN); -#endif /* BFD_BSD */ - - /* Construct UDP header information */ -#ifdef BFD_LINUX - ep.udp.source = htons(BFD_DEF_ECHO_PORT); - ep.udp.dest = htons(BFD_DEF_ECHO_PORT); - ep.udp.len = htons(UDP_ECHO_PKT_LEN); -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - ep.udp.uh_sport = htons(BFD_DEF_ECHO_PORT); - ep.udp.uh_dport = htons(BFD_DEF_ECHO_PORT); - ep.udp.uh_ulen = htons(UDP_ECHO_PKT_LEN); -#endif /* BFD_BSD */ - - /* Construct Echo packet information */ - ep.data.ver = BFD_ECHO_VERSION; - ep.data.len = BFD_ECHO_PKT_LEN; - ep.data.my_discr = htonl(bfd->discrs.my_discr); -#ifdef BFD_LINUX - ep.udp.check = -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - ep.udp.uh_sum = -#endif /* BFD_BSD */ - udp4_checksum(&ep.ip, (uint8_t *)&ep.udp, - UDP_ECHO_PKT_LEN); - - memcpy(pkt, &ep, sizeof(ep)); -} - void ptm_bfd_echo_snd(struct bfd_session *bfd) { - struct bfd_raw_echo_pkt *ep; - bool use_layer2 = false; - const void *pkt; - size_t pktlen; - uint16_t port = htons(BFD_DEF_ECHO_PORT); + struct sockaddr_any *sa; + socklen_t salen; + int sd; + struct bfd_echo_pkt bep; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; - if (!BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) { - ptm_bfd_echo_pkt_create(bfd); + if (!BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE); - } else { - /* just update the checksum and ip Id */ - ep = (struct bfd_raw_echo_pkt *)(bfd->echo_pkt + ETH_HDR_LEN); -#ifdef BFD_LINUX - ep->ip.id = htons(ptm_bfd_gen_IP_ID(bfd)); - ep->ip.check = 0; - ep->ip.check = checksum((uint16_t *)&ep->ip, IP_HDR_LEN); -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - ep->ip.ip_id = htons(ptm_bfd_gen_IP_ID(bfd)); - ep->ip.ip_sum = 0; - ep->ip.ip_sum = checksum((uint16_t *)&ep->ip, IP_HDR_LEN); -#endif /* BFD_BSD */ - } - if (use_layer2) { - pkt = bfd->echo_pkt; - pktlen = BFD_ECHO_PKT_TOT_LEN; + memset(&bep, 0, sizeof(bep)); + bep.ver = BFD_ECHO_VERSION; + bep.len = BFD_ECHO_PKT_LEN; + bep.my_discr = htonl(bfd->discrs.my_discr); + + sa = BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_MH) ? &bfd->mhop.peer + : &bfd->shop.peer; + if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6)) { + sd = bglobal.bg_echov6; + sin6 = sa->sa_sin6; + sin6.sin6_port = htons(BFD_DEF_ECHO_PORT); +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + sin6.sin6_len = sizeof(sin6); +#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ + + sa = (struct sockaddr_any *)&sin6; + salen = sizeof(sin6); } else { - pkt = &bfd->echo_pkt[ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN]; - pktlen = BFD_ECHO_PKT_TOT_LEN - - (ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN); - } + sd = bglobal.bg_echo; + sin = sa->sa_sin; + sin.sin_port = htons(BFD_DEF_ECHO_PORT); +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + sin.sin_len = sizeof(sin); +#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ - if (_ptm_bfd_send(bfd, use_layer2, &port, pkt, pktlen) != 0) { - log_debug("echo-packet: send failure: %s", strerror(errno)); - return; + sa = (struct sockaddr_any *)&sin; + salen = sizeof(sin); } + if (bp_udp_send(sd, BFD_TTL_VAL, (uint8_t *)&bep, sizeof(bep), + (struct sockaddr *)sa, salen) + == -1) + return; bfd->stats.tx_echo_pkt++; } -static int ptm_bfd_echo_loopback(uint8_t *pkt, int pkt_len, struct sockaddr *ss, - socklen_t sslen) -{ -#ifdef BFD_LINUX - struct bfd_raw_echo_pkt *ep = - (struct bfd_raw_echo_pkt *)(pkt + ETH_HDR_LEN); - uint8_t temp_mac[ETHERNET_ADDRESS_LENGTH]; - uint32_t temp_ip; - struct ethhdr *eth = (struct ethhdr *)pkt; - - /* swap the mac addresses */ - memcpy(temp_mac, eth->h_source, ETHERNET_ADDRESS_LENGTH); - memcpy(eth->h_source, eth->h_dest, ETHERNET_ADDRESS_LENGTH); - memcpy(eth->h_dest, temp_mac, ETHERNET_ADDRESS_LENGTH); - - /* swap ip addresses */ - temp_ip = ep->ip.saddr; - ep->ip.saddr = ep->ip.daddr; - ep->ip.daddr = temp_ip; - - ep->ip.ttl = ep->ip.ttl - 1; - ep->ip.check = 0; - ep->ip.check = checksum((uint16_t *)ep, IP_HDR_LEN); -#endif /* BFD_LINUX */ -#ifdef BFD_BSD_FILTER - struct bfd_raw_echo_pkt_t *ep = - (struct bfd_raw_echo_pkt *)(pkt + ETH_HDR_LEN); - uint8_t temp_mac[ETHERNET_ADDRESS_LENGTH]; - struct in_addr temp_ip; - struct ether_header *ether = (struct ether_header *)pkt; - - /* - * TODO: this is not yet implemented and requires BPF code for - * OmniOS, NetBSD and FreeBSD9. - */ - - /* swap the mac addresses */ - memcpy(temp_mac, ether->ether_shost, ETHERNET_ADDRESS_LENGTH); - memcpy(ether->ether_shost, ether->ether_dhost, ETHERNET_ADDRESS_LENGTH); - memcpy(ether->ether_dhost, temp_mac, ETHERNET_ADDRESS_LENGTH); - - /* swap ip addresses */ - temp_ip = ep->ip.ip_src; - ep->ip.ip_src = ep->ip.ip_dst; - ep->ip.ip_dst = temp_ip; - - ep->ip.ip_ttl = ep->ip.ip_ttl - 1; - ep->ip.ip_sum = 0; - ep->ip.ip_sum = checksum((uint16_t *)ep, IP_HDR_LEN); -#endif /* BFD_BSD_FILTER */ - - if (sendto(bglobal.bg_echo, pkt, pkt_len, 0, ss, sslen) < 0) { - log_debug("echo-loopback: send failure: %s", strerror(errno)); - return -1; - } - - return 0; -} - -static void ptm_bfd_vxlan_pkt_snd(struct bfd_session *bfd - __attribute__((__unused__)), - int fbit __attribute__((__unused__))) -{ -#if 0 /* TODO: VxLAN support. */ - struct bfd_raw_ctrl_pkt cp; - uint8_t vxlan_pkt[BFD_VXLAN_PKT_TOT_LEN]; - uint8_t *pkt = vxlan_pkt; - struct sockaddr_in sin; - struct vxlan_hdr *vhdr; - - memset(vxlan_pkt, 0, sizeof(vxlan_pkt)); - memset(&cp, 0, sizeof(cp)); - - /* Construct VxLAN header information */ - vhdr = (struct vxlan_hdr *)pkt; - vhdr->flags = htonl(0x08000000); - vhdr->vnid = htonl(bfd->vxlan_info.vnid << 8); - pkt += VXLAN_HDR_LEN; - - /* Construct ethernet header information */ - memcpy(pkt, bfd->vxlan_info.peer_dst_mac, ETHERNET_ADDRESS_LENGTH); - pkt = pkt + ETHERNET_ADDRESS_LENGTH; - memcpy(pkt, bfd->vxlan_info.local_dst_mac, ETHERNET_ADDRESS_LENGTH); - pkt = pkt + ETHERNET_ADDRESS_LENGTH; - pkt[0] = ETH_P_IP / 256; - pkt[1] = ETH_P_IP % 256; - pkt += 2; - - /* Construct IP header information */ - cp.ip.version = 4; - cp.ip.ihl = 5; - cp.ip.tos = 0; - cp.ip.tot_len = htons(IP_CTRL_PKT_LEN); - cp.ip.id = ptm_bfd_gen_IP_ID(bfd); - cp.ip.frag_off = 0; - cp.ip.ttl = BFD_TTL_VAL; - cp.ip.protocol = IPPROTO_UDP; - cp.ip.daddr = bfd->vxlan_info.peer_dst_ip.s_addr; - cp.ip.saddr = bfd->vxlan_info.local_dst_ip.s_addr; - cp.ip.check = checksum((uint16_t *)&cp.ip, IP_HDR_LEN); - - /* Construct UDP header information */ - cp.udp.source = htons(BFD_DEFDESTPORT); - cp.udp.dest = htons(BFD_DEFDESTPORT); - cp.udp.len = htons(UDP_CTRL_PKT_LEN); - - /* Construct BFD control packet information */ - cp.data.diag = bfd->local_diag; - BFD_SETVER(cp.data.diag, BFD_VERSION); - BFD_SETSTATE(cp.data.flags, bfd->ses_state); - BFD_SETDEMANDBIT(cp.data.flags, BFD_DEF_DEMAND); - BFD_SETPBIT(cp.data.flags, bfd->polling); - BFD_SETFBIT(cp.data.flags, fbit); - cp.data.detect_mult = bfd->detect_mult; - cp.data.len = BFD_PKT_LEN; - cp.data.discrs.my_discr = htonl(bfd->discrs.my_discr); - cp.data.discrs.remote_discr = htonl(bfd->discrs.remote_discr); - cp.data.timers.desired_min_tx = htonl(bfd->timers.desired_min_tx); - cp.data.timers.required_min_rx = htonl(bfd->timers.required_min_rx); - cp.data.timers.required_min_echo = htonl(bfd->timers.required_min_echo); - - cp.udp.check = - udp4_checksum(&cp.ip, (uint8_t *)&cp.udp, UDP_CTRL_PKT_LEN); - - memcpy(pkt, &cp, sizeof(cp)); - sin.sin_family = AF_INET; - sin.sin_addr = bfd->shop.peer.sa_sin.sin_addr; - sin.sin_port = htons(4789); - - if (sendto(bfd->sock, vxlan_pkt, BFD_VXLAN_PKT_TOT_LEN, 0, - (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) - < 0) { - ERRLOG("Error sending vxlan bfd pkt: %s", strerror(errno)); - } else { - bfd->stats.tx_ctrl_pkt++; - } -#endif -} - static int ptm_bfd_process_echo_pkt(int s) { - uint32_t my_discr = 0; - struct sockaddr_storage ss; - socklen_t sslen = sizeof(ss); - uint8_t rx_pkt[BFD_RX_BUF_LEN]; - ssize_t pkt_len = sizeof(rx_pkt); struct bfd_session *bfd; -#ifdef BFD_LINUX - struct bfd_raw_echo_pkt *ep; - - /* - * valgrind: memset() ss so valgrind doesn't complain about - * uninitialized memory. - */ - memset(&ss, 0, sizeof(ss)); - pkt_len = recvfrom(s, rx_pkt, sizeof(rx_pkt), MSG_DONTWAIT, - (struct sockaddr *)&ss, &sslen); - if (pkt_len <= 0) { - if (errno != EAGAIN) - log_error("echo-packet: read failure: %s", - strerror(errno)); - - return -1; - } - - /* Check if we have at least the basic headers to send back. */ - if (pkt_len < BFD_ECHO_PKT_TOT_LEN) { - log_debug("echo-packet: too short (got %ld, expected %d)", - pkt_len, BFD_ECHO_PKT_TOT_LEN); - return -1; - } - - ep = (struct bfd_raw_echo_pkt *)(rx_pkt + ETH_HDR_LEN); - /* if TTL = 255, assume that the received echo packet has - * to be looped back - */ - if (ep->ip.ttl == BFD_TTL_VAL) - return ptm_bfd_echo_loopback(rx_pkt, pkt_len, - (struct sockaddr *)&ss, - sizeof(struct sockaddr_ll)); - - my_discr = ntohl(ep->data.my_discr); - if (ep->data.my_discr == 0) { - log_debug("echo-packet: 'my discriminator' is zero"); - return -1; - } -#endif /* BFD_LINUX */ -#ifdef BFD_BSD - int rv; - uint8_t ttl; - - /* - * bsd_echo_sock_read() already treats invalid TTL values and - * zeroed discriminators. - */ - rv = bsd_echo_sock_read(s, rx_pkt, &pkt_len, &ss, &sslen, &ttl, - &my_discr); - if (rv == -1) - return -1; + uint32_t my_discr = 0; + uint8_t ttl = 0; - if (ttl == BFD_TTL_VAL) - return ptm_bfd_echo_loopback(rx_pkt, pkt_len, - (struct sockaddr *)&ss, sslen); -#endif /* BFD_BSD */ + /* Receive and parse echo packet. */ + if (bp_bfd_echo_in(s, &ttl, &my_discr) == -1) + return 0; /* Your discriminator not zero - use it to find session */ bfd = bfd_id_lookup(my_discr); @@ -554,8 +186,8 @@ static int ptm_bfd_process_echo_pkt(int s) } if (!BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) { - log_debug("echo-packet: echo disabled [%s]", my_discr, - bs_to_string(bfd)); + log_debug("echo-packet: echo disabled [%s] (id:%u)", + bs_to_string(bfd), my_discr); return -1; } @@ -574,14 +206,6 @@ void ptm_bfd_snd(struct bfd_session *bfd, int fbit) { struct bfd_pkt cp; - /* if the BFD session is for VxLAN tunnel, then construct and - * send bfd raw packet - */ - if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_VXLAN)) { - ptm_bfd_vxlan_pkt_snd(bfd, fbit); - return; - } - /* Set fields according to section 6.5.7 */ cp.diag = bfd->local_diag; BFD_SETVER(cp.diag, BFD_VERSION); @@ -605,98 +229,16 @@ void ptm_bfd_snd(struct bfd_session *bfd, int fbit) } cp.timers.required_min_echo = htonl(bfd->timers.required_min_echo); - if (_ptm_bfd_send(bfd, false, NULL, &cp, BFD_PKT_LEN) != 0) + if (_ptm_bfd_send(bfd, NULL, &cp, BFD_PKT_LEN) != 0) return; bfd->stats.tx_ctrl_pkt++; } -#if 0 /* TODO VxLAN Support */ -static struct bfd_pkt * -ptm_bfd_process_vxlan_pkt(int s, ptm_sockevent_e se, void *udata, int *ifindex, - struct sockaddr_in *sin, - struct bfd_session_vxlan_info_t *vxlan_info, - uint8_t *rx_pkt, int *mlen) -{ - struct sockaddr_ll sll; - uint32_t from_len = sizeof(struct sockaddr_ll); - struct bfd_raw_ctrl_pkt *cp; - uint8_t *pkt = rx_pkt; - struct iphdr *iph; - struct ethhdr *inner_ethh; - - *mlen = recvfrom(s, rx_pkt, BFD_RX_BUF_LEN, MSG_DONTWAIT, - (struct sockaddr *)&sll, &from_len); - - if (*mlen < 0) { - if (errno != EAGAIN) - ERRLOG("Error receiving from BFD Vxlan socket %d: %m", - s); - return NULL; - } - - iph = (struct iphdr *)(pkt + ETH_HDR_LEN); - pkt = pkt + ETH_HDR_LEN + IP_HDR_LEN + UDP_HDR_LEN; - vxlan_info->vnid = ntohl(*((int *)(pkt + 4))); - vxlan_info->vnid = vxlan_info->vnid >> 8; - - pkt = pkt + VXLAN_HDR_LEN; - inner_ethh = (struct ethhdr *)pkt; - - cp = (struct bfd_raw_ctrl_pkt *)(pkt + ETH_HDR_LEN); - - /* Discard the non BFD packets */ - if (ntohs(cp->udp.dest) != BFD_DEFDESTPORT) - return NULL; - - *ifindex = sll.sll_ifindex; - sin->sin_addr.s_addr = iph->saddr; - sin->sin_port = ntohs(cp->udp.dest); - - vxlan_info->local_dst_ip.s_addr = cp->ip.daddr; - memcpy(vxlan_info->local_dst_mac, inner_ethh->h_dest, - ETHERNET_ADDRESS_LENGTH); - - return &cp->data; -} -#endif /* VxLAN */ - -static bool -ptm_bfd_validate_vxlan_pkt(struct bfd_session *bfd, - struct bfd_session_vxlan_info *vxlan_info) -{ - if (bfd->vxlan_info.check_tnl_key && (vxlan_info->vnid != 0)) { - log_error("vxlan-packet: vnid not zero: %d", vxlan_info->vnid); - return false; - } - - if (bfd->vxlan_info.local_dst_ip.s_addr - != vxlan_info->local_dst_ip.s_addr) { - log_error("vxlan-packet: wrong inner destination", - inet_ntoa(vxlan_info->local_dst_ip)); - return false; - } - - if (memcmp(bfd->vxlan_info.local_dst_mac, vxlan_info->local_dst_mac, - ETHERNET_ADDRESS_LENGTH)) { - log_error( - "vxlan-packet: wrong inner mac: %02x:%02x:%02x:%02x:%02x:%02x", - vxlan_info->local_dst_mac[0], - vxlan_info->local_dst_mac[1], - vxlan_info->local_dst_mac[2], - vxlan_info->local_dst_mac[3], - vxlan_info->local_dst_mac[4], - vxlan_info->local_dst_mac[5]); - return false; - } - - return true; -} - -static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, - char *vrfname, size_t vrfnamelen, - struct sockaddr_any *local, - struct sockaddr_any *peer) +ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, + char *port, size_t portlen, char *vrfname, + size_t vrfnamelen, struct sockaddr_any *local, + struct sockaddr_any *peer) { struct cmsghdr *cm; int ifindex; @@ -708,7 +250,7 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, /* Prepare the recvmsg params. */ iov[0].iov_base = msgbuf; - iov[0].iov_len = sizeof(msgbuf); + iov[0].iov_len = msgbuflen; memset(&msghdr, 0, sizeof(msghdr)); msghdr.msg_name = &msgaddr; @@ -739,16 +281,14 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, switch (cm->cmsg_type) { #ifdef BFD_LINUX case IP_TTL: { - uint32_t ttl; - - memcpy(&ttl, CMSG_DATA(cm), sizeof(ttl)); - if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) { - log_debug( - "ipv4-recv: invalid TTL from %s (expected %d, got %d flags %d)", - satostr(peer), ttl, BFD_TTL_VAL, - msghdr.msg_flags); + uint32_t ttlval; + + memcpy(&ttlval, CMSG_DATA(cm), sizeof(ttlval)); + if (ttlval > 255) { + log_debug("ipv4-recv: invalid TTL: %u", ttlval); return -1; } + *ttl = ttlval; break; } @@ -768,16 +308,7 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, #endif /* BFD_LINUX */ #ifdef BFD_BSD case IP_RECVTTL: { - uint8_t ttl; - - memcpy(&ttl, CMSG_DATA(cm), sizeof(ttl)); - if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) { - log_debug( - "ipv4-recv: invalid TTL from %s (expected %d, got %d flags %d)", - satostr(peer), ttl, BFD_TTL_VAL, - msghdr.msg_flags); - return -1; - } + memcpy(ttl, CMSG_DATA(cm), sizeof(*ttl)); break; } @@ -812,14 +343,16 @@ static ssize_t bfd_recv_ipv4(int sd, bool is_mhop, char *port, size_t portlen, return mlen; } -ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, - char *vrfname, size_t vrfnamelen, - struct sockaddr_any *local, struct sockaddr_any *peer) +ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl, + char *port, size_t portlen, char *vrfname, + size_t vrfnamelen, struct sockaddr_any *local, + struct sockaddr_any *peer) { struct cmsghdr *cm; struct in6_pktinfo *pi6 = NULL; int ifindex = 0; ssize_t mlen; + uint32_t ttlval; struct sockaddr_in6 msgaddr6; struct msghdr msghdr6; struct iovec iov[1]; @@ -827,7 +360,7 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, /* Prepare the recvmsg params. */ iov[0].iov_base = msgbuf; - iov[0].iov_len = sizeof(msgbuf); + iov[0].iov_len = msgbuflen; memset(&msghdr6, 0, sizeof(msghdr6)); msghdr6.msg_name = &msgaddr6; @@ -840,7 +373,7 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, mlen = recvmsg(sd, &msghdr6, MSG_DONTWAIT); if (mlen == -1) { if (errno != EAGAIN) - log_error("ipv4-recv: recv failed: %s", + log_error("ipv6-recv: recv failed: %s", strerror(errno)); return -1; @@ -856,14 +389,13 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, continue; if (cm->cmsg_type == IPV6_HOPLIMIT) { - memcpy(&ttlval, CMSG_DATA(cm), 4); - if ((is_mhop == false) && (ttlval != BFD_TTL_VAL)) { - log_debug( - "ipv6-recv: invalid TTL from %s (expected %d, got %d flags %d)", - satostr(peer), ttlval, BFD_TTL_VAL, - msghdr6.msg_flags); + memcpy(&ttlval, CMSG_DATA(cm), sizeof(ttlval)); + if (ttlval > 255) { + log_debug("ipv6-recv: invalid TTL: %u", ttlval); return -1; } + + *ttl = ttlval; } else if (cm->cmsg_type == IPV6_PKTINFO) { pi6 = (struct in6_pktinfo *)CMSG_DATA(cm); if (pi6) { @@ -888,28 +420,28 @@ ssize_t bfd_recv_ipv6(int sd, bool is_mhop, char *port, size_t portlen, static void bfd_sd_reschedule(int sd) { if (sd == bglobal.bg_shop) { - bglobal.bg_ev[0] = NULL; + THREAD_OFF(bglobal.bg_ev[0]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_shop, &bglobal.bg_ev[0]); } else if (sd == bglobal.bg_mhop) { - bglobal.bg_ev[1] = NULL; + THREAD_OFF(bglobal.bg_ev[1]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_mhop, &bglobal.bg_ev[1]); } else if (sd == bglobal.bg_shop6) { - bglobal.bg_ev[2] = NULL; + THREAD_OFF(bglobal.bg_ev[2]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_shop6, &bglobal.bg_ev[2]); } else if (sd == bglobal.bg_mhop6) { - bglobal.bg_ev[3] = NULL; + THREAD_OFF(bglobal.bg_ev[3]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_mhop6, &bglobal.bg_ev[3]); } else if (sd == bglobal.bg_echo) { - bglobal.bg_ev[4] = NULL; + THREAD_OFF(bglobal.bg_ev[4]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echo, &bglobal.bg_ev[4]); - } else if (sd == bglobal.bg_vxlan) { - bglobal.bg_ev[5] = NULL; - thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_vxlan, + } else if (sd == bglobal.bg_echov6) { + THREAD_OFF(bglobal.bg_ev[5]); + thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echov6, &bglobal.bg_ev[5]); } } @@ -955,18 +487,19 @@ int bfd_recv_cb(struct thread *t) int sd = THREAD_FD(t); struct bfd_session *bfd; struct bfd_pkt *cp; - bool is_mhop, is_vxlan; + bool is_mhop; ssize_t mlen = 0; uint32_t oldEchoXmt_TO, oldXmtTime; + uint8_t ttl; struct sockaddr_any local, peer; char port[MAXNAMELEN + 1], vrfname[MAXNAMELEN + 1]; - struct bfd_session_vxlan_info vxlan_info; + uint8_t msgbuf[1516]; /* Schedule next read. */ bfd_sd_reschedule(sd); /* Handle echo packets. */ - if (sd == bglobal.bg_echo) { + if (sd == bglobal.bg_echo || sd == bglobal.bg_echov6) { ptm_bfd_process_echo_pkt(sd); return 0; } @@ -978,28 +511,18 @@ int bfd_recv_cb(struct thread *t) memset(&peer, 0, sizeof(peer)); /* Handle control packets. */ - is_mhop = is_vxlan = false; + is_mhop = false; if (sd == bglobal.bg_shop || sd == bglobal.bg_mhop) { is_mhop = sd == bglobal.bg_mhop; - mlen = bfd_recv_ipv4(sd, is_mhop, port, sizeof(port), vrfname, - sizeof(vrfname), &local, &peer); + mlen = bfd_recv_ipv4(sd, msgbuf, sizeof(msgbuf), &ttl, port, + sizeof(port), vrfname, sizeof(vrfname), + &local, &peer); } else if (sd == bglobal.bg_shop6 || sd == bglobal.bg_mhop6) { is_mhop = sd == bglobal.bg_mhop6; - mlen = bfd_recv_ipv6(sd, is_mhop, port, sizeof(port), vrfname, - sizeof(vrfname), &local, &peer); + mlen = bfd_recv_ipv6(sd, msgbuf, sizeof(msgbuf), &ttl, port, + sizeof(port), vrfname, sizeof(vrfname), + &local, &peer); } -#if 0 /* TODO vxlan handling */ - cp = ptm_bfd_process_vxlan_pkt(s, se, udata, &local_ifindex, - &sin, &vxlan_info, rx_pkt, &mlen); - if (!cp) - return -1; - - is_vxlan = true; - /* keep in network-byte order */ - peer.ip4_addr.s_addr = sin.sin_addr.s_addr; - peer.family = AF_INET; - strcpy(peer_addr, inet_ntoa(sin.sin_addr)); -#endif /* Implement RFC 5880 6.8.6 */ if (mlen < BFD_PKT_LEN) { @@ -1008,6 +531,13 @@ int bfd_recv_cb(struct thread *t) return 0; } + /* Validate packet TTL. */ + if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) { + cp_debug(is_mhop, &peer, &local, port, vrfname, + "invalid TTL: %d expected %d", ttl, BFD_TTL_VAL); + return 0; + } + /* * Parse the control header for inconsistencies: * - Invalid version; @@ -1047,10 +577,6 @@ int bfd_recv_cb(struct thread *t) return 0; } - /* Handle VxLAN cases. */ - if (is_vxlan && !ptm_bfd_validate_vxlan_pkt(bfd, &vxlan_info)) - return 0; - bfd->stats.rx_ctrl_pkt++; /* @@ -1058,10 +584,10 @@ int bfd_recv_cb(struct thread *t) * Single hop: set local address that received the packet. */ if (is_mhop) { - if ((BFD_TTL_VAL - bfd->mh_ttl) > ttlval) { + if ((BFD_TTL_VAL - bfd->mh_ttl) > BFD_TTL_VAL) { cp_debug(is_mhop, &peer, &local, port, vrfname, "exceeded max hop count (expected %d, got %d)", - bfd->mh_ttl, ttlval); + bfd->mh_ttl, BFD_TTL_VAL); return 0; } } else if (bfd->local_ip.sa_sin.sin_family == AF_UNSPEC) { @@ -1111,7 +637,7 @@ int bfd_recv_cb(struct thread *t) /* State switch from section 6.8.6 */ if (BFD_GETSTATE(cp->flags) == PTM_BFD_ADM_DOWN) { if (bfd->ses_state != PTM_BFD_DOWN) - ptm_bfd_ses_dn(bfd, BFD_DIAGNEIGHDOWN); + ptm_bfd_ses_dn(bfd, BD_NEIGHBOR_DOWN); } else { switch (bfd->ses_state) { case (PTM_BFD_DOWN): @@ -1127,7 +653,7 @@ int bfd_recv_cb(struct thread *t) break; case (PTM_BFD_UP): if (BFD_GETSTATE(cp->flags) == PTM_BFD_DOWN) - ptm_bfd_ses_dn(bfd, BFD_DIAGNEIGHDOWN); + ptm_bfd_ses_dn(bfd, BD_NEIGHBOR_DOWN); break; } } @@ -1209,6 +735,121 @@ int bfd_recv_cb(struct thread *t) return 0; } +/* + * bp_bfd_echo_in: proccesses an BFD echo packet. On TTL == BFD_TTL_VAL + * the packet is looped back or returns the my discriminator ID along + * with the TTL. + * + * Returns -1 on error or loopback or 0 on success. + */ +int bp_bfd_echo_in(int sd, uint8_t *ttl, uint32_t *my_discr) +{ + struct bfd_echo_pkt *bep; + ssize_t rlen; + struct sockaddr_any local, peer; + char port[MAXNAMELEN + 1], vrfname[MAXNAMELEN + 1]; + uint8_t msgbuf[1516]; + + if (sd == bglobal.bg_echo) + rlen = bfd_recv_ipv4(sd, msgbuf, sizeof(msgbuf), ttl, port, + sizeof(port), vrfname, sizeof(vrfname), + &local, &peer); + else + rlen = bfd_recv_ipv6(sd, msgbuf, sizeof(msgbuf), ttl, port, + sizeof(port), vrfname, sizeof(vrfname), + &local, &peer); + + /* Short packet, better not risk reading it. */ + if (rlen < (ssize_t)sizeof(*bep)) { + cp_debug(false, &peer, &local, port, vrfname, + "small echo packet"); + return -1; + } + + /* Test for loopback. */ + if (*ttl == BFD_TTL_VAL) { + bp_udp_send(sd, *ttl - 1, msgbuf, rlen, + (struct sockaddr *)&peer, + (sd == bglobal.bg_echo) ? sizeof(peer.sa_sin) + : sizeof(peer.sa_sin6)); + return -1; + } + + /* Read my discriminator from BFD Echo packet. */ + bep = (struct bfd_echo_pkt *)msgbuf; + *my_discr = ntohl(bep->my_discr); + if (*my_discr == 0) { + cp_debug(false, &peer, &local, port, vrfname, + "invalid echo packet discriminator (zero)"); + return -1; + } + + return 0; +} + +int bp_udp_send(int sd, uint8_t ttl, uint8_t *data, size_t datalen, + struct sockaddr *to, socklen_t tolen) +{ + struct cmsghdr *cmsg; + ssize_t wlen; + int ttlval = ttl; + bool is_ipv6 = to->sa_family == AF_INET6; + struct msghdr msg; + struct iovec iov[1]; + uint8_t msgctl[255]; + + /* Prepare message data. */ + iov[0].iov_base = data; + iov[0].iov_len = datalen; + + memset(&msg, 0, sizeof(msg)); + memset(msgctl, 0, sizeof(msgctl)); + msg.msg_name = to; + msg.msg_namelen = tolen; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + /* Prepare the packet TTL information. */ + if (ttl > 0) { + /* Use ancillary data. */ + msg.msg_control = msgctl; + msg.msg_controllen = CMSG_LEN(sizeof(ttlval)); + + /* Configure the ancillary data. */ + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(ttlval)); + if (is_ipv6) { + cmsg->cmsg_level = IPPROTO_IPV6; + cmsg->cmsg_type = IPV6_HOPLIMIT; + } else { +#if BFD_LINUX + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_TTL; +#else + /* FreeBSD does not support TTL in ancillary data. */ + msg.msg_control = NULL; + msg.msg_controllen = 0; + + bp_set_ttl(sd, ttl); +#endif /* BFD_BSD */ + } + memcpy(CMSG_DATA(cmsg), &ttlval, sizeof(ttlval)); + } + + /* Send echo back. */ + wlen = sendmsg(sd, &msg, 0); + if (wlen <= 0) { + log_debug("udp-send: loopback failure: (%d) %s", errno, strerror(errno)); + return -1; + } else if (wlen < (ssize_t)datalen) { + log_debug("udp-send: partial send: %ld expected %ld", wlen, + datalen); + return -1; + } + + return 0; +} + /* * Sockets creation. @@ -1218,10 +859,12 @@ int bfd_recv_cb(struct thread *t) /* * IPv4 sockets */ -int bp_set_ttl(int sd) +int bp_set_ttl(int sd, uint8_t value) { - if (setsockopt(sd, IPPROTO_IP, IP_TTL, &ttlval, sizeof(ttlval)) == -1) { - log_warning("%s: setsockopt(IP_TTL): %s", __func__, + int ttl = value; + + if (setsockopt(sd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) { + log_warning("set-ttl: setsockopt(IP_TTL, %d): %s", value, strerror(errno)); return -1; } @@ -1229,10 +872,12 @@ int bp_set_ttl(int sd) return 0; } -int bp_set_tos(int sd) +int bp_set_tos(int sd, uint8_t value) { - if (setsockopt(sd, IPPROTO_IP, IP_TOS, &tosval, sizeof(tosval)) == -1) { - log_warning("%s: setsockopt(IP_TOS): %s", __func__, + int tos = value; + + if (setsockopt(sd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == -1) { + log_warning("set-tos: setsockopt(IP_TOS, %d): %s", value, strerror(errno)); return -1; } @@ -1242,20 +887,23 @@ int bp_set_tos(int sd) static void bp_set_ipopts(int sd) { - if (bp_set_ttl(sd) != 0) - log_fatal("%s: TTL configuration failed", __func__); + int rcvttl = BFD_RCV_TTL_VAL; + + if (bp_set_ttl(sd, BFD_TTL_VAL) != 0) + log_fatal("set-ipopts: TTL configuration failed"); if (setsockopt(sd, IPPROTO_IP, IP_RECVTTL, &rcvttl, sizeof(rcvttl)) == -1) - log_fatal("%s: setsockopt(IP_RECVTTL): %s", __func__, + log_fatal("set-ipopts: setsockopt(IP_RECVTTL, %d): %s", rcvttl, strerror(errno)); #ifdef BFD_LINUX int pktinfo = BFD_PKT_INFO_VAL; + /* Figure out address and interface to do the peer matching. */ if (setsockopt(sd, IPPROTO_IP, IP_PKTINFO, &pktinfo, sizeof(pktinfo)) == -1) - log_fatal("%s: setsockopt(IP_PKTINFO): %s", __func__, + log_fatal("set-ipopts: setsockopt(IP_PKTINFO, %d): %s", pktinfo, strerror(errno)); #endif /* BFD_LINUX */ #ifdef BFD_BSD @@ -1263,12 +911,12 @@ static void bp_set_ipopts(int sd) /* Find out our address for peer matching. */ if (setsockopt(sd, IPPROTO_IP, IP_RECVDSTADDR, &yes, sizeof(yes)) == -1) - log_fatal("%s: setsockopt(IP_RECVDSTADDR): %s", __func__, + log_fatal("set-ipopts: setsockopt(IP_RECVDSTADDR, %d): %s", yes, strerror(errno)); /* Find out interface where the packet came in. */ if (setsockopt_ifindex(AF_INET, sd, yes) == -1) - log_fatal("%s: setsockopt_ipv4_ifindex: %s", __func__, + log_fatal("set-ipopts: setsockopt_ipv4_ifindex(%d): %s", yes, strerror(errno)); #endif /* BFD_BSD */ } @@ -1282,7 +930,7 @@ static void bp_bind_ip(int sd, uint16_t port) sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(port); if (bind(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1) - log_fatal("%s: bind: %s", __func__, strerror(errno)); + log_fatal("bind-ip: bind: %s", strerror(errno)); } int bp_udp_shop(void) @@ -1291,7 +939,7 @@ int bp_udp_shop(void) sd = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC); if (sd == -1) - log_fatal("%s: socket: %s", __func__, strerror(errno)); + log_fatal("udp-shop: socket: %s", strerror(errno)); bp_set_ipopts(sd); bp_bind_ip(sd, BFD_DEFDESTPORT); @@ -1305,7 +953,7 @@ int bp_udp_mhop(void) sd = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC); if (sd == -1) - log_fatal("%s: socket: %s", __func__, strerror(errno)); + log_fatal("udp-mhop: socket: %s", strerror(errno)); bp_set_ipopts(sd); bp_bind_ip(sd, BFD_DEF_MHOP_DEST_PORT); @@ -1326,22 +974,19 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc) return -1; } - if (!bpc->bpc_has_vxlan) { - /* Set TTL to 255 for all transmitted packets */ - if (bp_set_ttl(sd) != 0) { - close(sd); - return -1; - } + /* Set TTL to 255 for all transmitted packets */ + if (bp_set_ttl(sd, BFD_TTL_VAL) != 0) { + close(sd); + return -1; } /* Set TOS to CS6 for all transmitted packets */ - if (bp_set_tos(sd) != 0) { + if (bp_set_tos(sd, BFD_TOS_VAL) != 0) { close(sd); return -1; } - /* dont bind-to-device incase of vxlan */ - if (!bpc->bpc_has_vxlan && bpc->bpc_has_localif) { + if (bpc->bpc_has_localif) { if (bp_bind_dev(sd, bpc->bpc_localif) != 0) { close(sd); return -1; @@ -1360,7 +1005,7 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc) #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN sin.sin_len = sizeof(sin); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ - if (bpc->bpc_mhop || bpc->bpc_has_vxlan) + if (bpc->bpc_mhop) sin.sin_addr = bpc->bpc_local.sa_sin.sin_addr; else sin.sin_addr.s_addr = INADDR_ANY; @@ -1400,16 +1045,14 @@ int bp_peer_socketv6(struct bfd_peer_cfg *bpc) return -1; } - if (!bpc->bpc_has_vxlan) { - /* Set TTL to 255 for all transmitted packets */ - if (bp_set_ttlv6(sd) != 0) { - close(sd); - return -1; - } + /* Set TTL to 255 for all transmitted packets */ + if (bp_set_ttlv6(sd, BFD_TTL_VAL) != 0) { + close(sd); + return -1; } /* Set TOS to CS6 for all transmitted packets */ - if (bp_set_tosv6(sd) != 0) { + if (bp_set_tosv6(sd, BFD_TOS_VAL) != 0) { close(sd); return -1; } @@ -1454,24 +1097,27 @@ int bp_peer_socketv6(struct bfd_peer_cfg *bpc) return sd; } -int bp_set_ttlv6(int sd) +int bp_set_ttlv6(int sd, uint8_t value) { - if (setsockopt(sd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttlval, - sizeof(ttlval)) + int ttl = value; + + if (setsockopt(sd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) == -1) { - log_warning("%s: setsockopt(IPV6_UNICAST_HOPS): %s", __func__, - strerror(errno)); + log_warning("set-ttlv6: setsockopt(IPV6_UNICAST_HOPS, %d): %s", + value, strerror(errno)); return -1; } return 0; } -int bp_set_tosv6(int sd) +int bp_set_tosv6(int sd, uint8_t value) { - if (setsockopt(sd, IPPROTO_IPV6, IPV6_TCLASS, &tosval, sizeof(tosval)) + int tos = value; + + if (setsockopt(sd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) == -1) { - log_warning("%s: setsockopt(IPV6_TCLASS): %s", __func__, + log_warning("set-tosv6: setsockopt(IPV6_TCLASS, %d): %s", value, strerror(errno)); return -1; } @@ -1481,28 +1127,26 @@ int bp_set_tosv6(int sd) static void bp_set_ipv6opts(int sd) { - static int ipv6_pktinfo = BFD_IPV6_PKT_INFO_VAL; - static int ipv6_only = BFD_IPV6_ONLY_VAL; + int ipv6_pktinfo = BFD_IPV6_PKT_INFO_VAL; + int ipv6_only = BFD_IPV6_ONLY_VAL; - if (setsockopt(sd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttlval, - sizeof(ttlval)) - == -1) - log_fatal("%s: setsockopt(IPV6_UNICAST_HOPS): %s", __func__, - strerror(errno)); + if (bp_set_ttlv6(sd, BFD_TTL_VAL) == -1) + log_fatal("set-ipv6opts: setsockopt(IPV6_UNICAST_HOPS, %d): %s", + BFD_TTL_VAL, strerror(errno)); - if (setsockopt_ipv6_hoplimit(sd, rcvttl) == -1) - log_fatal("%s: setsockopt(IPV6_HOPLIMIT): %s", __func__, - strerror(errno)); + if (setsockopt_ipv6_hoplimit(sd, BFD_RCV_TTL_VAL) == -1) + log_fatal("set-ipv6opts: setsockopt(IPV6_HOPLIMIT, %d): %s", + BFD_RCV_TTL_VAL, strerror(errno)); if (setsockopt_ipv6_pktinfo(sd, ipv6_pktinfo) == -1) - log_fatal("%s: setsockopt(IPV6_PKTINFO): %s", __func__, - strerror(errno)); + log_fatal("set-ipv6opts: setsockopt(IPV6_PKTINFO, %d): %s", + ipv6_pktinfo, strerror(errno)); if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6_only, sizeof(ipv6_only)) == -1) - log_fatal("%s: setsockopt(IPV6_V6ONLY): %s", __func__, - strerror(errno)); + log_fatal("set-ipv6opts: setsockopt(IPV6_V6ONLY, %d): %s", + ipv6_only, strerror(errno)); } static void bp_bind_ipv6(int sd, uint16_t port) @@ -1517,7 +1161,7 @@ static void bp_bind_ipv6(int sd, uint16_t port) sin6.sin6_len = sizeof(sin6); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ if (bind(sd, (struct sockaddr *)&sin6, sizeof(sin6)) == -1) - log_fatal("%s: bind: %s", __func__, strerror(errno)); + log_fatal("bind-ipv6: bind: %s", strerror(errno)); } int bp_udp6_shop(void) @@ -1526,7 +1170,7 @@ int bp_udp6_shop(void) sd = socket(AF_INET6, SOCK_DGRAM, PF_UNSPEC); if (sd == -1) - log_fatal("%s: socket: %s", __func__, strerror(errno)); + log_fatal("udp6-shop: socket: %s", strerror(errno)); bp_set_ipv6opts(sd); bp_bind_ipv6(sd, BFD_DEFDESTPORT); @@ -1540,10 +1184,38 @@ int bp_udp6_mhop(void) sd = socket(AF_INET6, SOCK_DGRAM, PF_UNSPEC); if (sd == -1) - log_fatal("%s: socket: %s", __func__, strerror(errno)); + log_fatal("udp6-mhop: socket: %s", strerror(errno)); bp_set_ipv6opts(sd); bp_bind_ipv6(sd, BFD_DEF_MHOP_DEST_PORT); return sd; } + +int bp_echo_socket(void) +{ + int s; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == -1) + log_fatal("echo-socket: socket: %s", strerror(errno)); + + bp_set_ipopts(s); + bp_bind_ip(s, BFD_DEF_ECHO_PORT); + + return s; +} + +int bp_echov6_socket(void) +{ + int s; + + s = socket(AF_INET6, SOCK_DGRAM, 0); + if (s == -1) + log_fatal("echov6-socket: socket: %s", strerror(errno)); + + bp_set_ipv6opts(s); + bp_bind_ipv6(s, BFD_DEF_ECHO_PORT); + + return s; +} diff --git a/bfdd/bfdctl.h b/bfdd/bfdctl.h index 940efd1614..0da1ca8df6 100644 --- a/bfdd/bfdctl.h +++ b/bfdd/bfdctl.h @@ -66,9 +66,6 @@ struct bfd_peer_cfg { bool bpc_has_label; char bpc_label[MAXNAMELEN]; - bool bpc_has_vxlan; - unsigned int bpc_vxlan; - bool bpc_has_localif; char bpc_localif[MAXNAMELEN + 1]; diff --git a/bfdd/bfdd.c b/bfdd/bfdd.c index 144619088d..250f8d21c0 100644 --- a/bfdd/bfdd.c +++ b/bfdd/bfdd.c @@ -90,7 +90,6 @@ static void sigterm_handler(void) socket_close(&bglobal.bg_mhop); socket_close(&bglobal.bg_shop6); socket_close(&bglobal.bg_mhop6); - socket_close(&bglobal.bg_vxlan); /* Terminate and free() FRR related memory. */ frr_fini(); @@ -131,17 +130,22 @@ static struct option longopts[] = { struct bfd_global bglobal; struct bfd_diag_str_list diag_list[] = { - {.str = "NeighDown", .type = BFD_DIAGNEIGHDOWN}, - {.str = "DetectTime", .type = BFD_DIAGDETECTTIME}, - {.str = "AdminDown", .type = BFD_DIAGADMINDOWN}, + {.str = "control-expired", .type = BD_CONTROL_EXPIRED}, + {.str = "echo-failed", .type = BD_ECHO_FAILED}, + {.str = "neighbor-down", .type = BD_NEIGHBOR_DOWN}, + {.str = "forwarding-reset", .type = BD_FORWARDING_RESET}, + {.str = "path-down", .type = BD_PATH_DOWN}, + {.str = "concatenated-path-down", .type = BD_CONCATPATH_DOWN}, + {.str = "administratively-down", .type = BD_ADMIN_DOWN}, + {.str = "reverse-concat-path-down", .type = BD_REVCONCATPATH_DOWN}, {.str = NULL}, }; struct bfd_state_str_list state_list[] = { - {.str = "AdminDown", .type = PTM_BFD_ADM_DOWN}, - {.str = "Down", .type = PTM_BFD_DOWN}, - {.str = "Init", .type = PTM_BFD_INIT}, - {.str = "Up", .type = PTM_BFD_UP}, + {.str = "admin-down", .type = PTM_BFD_ADM_DOWN}, + {.str = "down", .type = PTM_BFD_DOWN}, + {.str = "init", .type = PTM_BFD_INIT}, + {.str = "up", .type = PTM_BFD_UP}, {.str = NULL}, }; @@ -154,8 +158,8 @@ static void bg_init(void) bglobal.bg_mhop = bp_udp_mhop(); bglobal.bg_shop6 = bp_udp6_shop(); bglobal.bg_mhop6 = bp_udp6_mhop(); - bglobal.bg_echo = ptm_bfd_echo_sock_init(); - bglobal.bg_vxlan = ptm_bfd_vxlan_sock_init(); + bglobal.bg_echo = bp_echo_socket(); + bglobal.bg_echov6 = bp_echov6_socket(); } int main(int argc, char *argv[]) @@ -216,10 +220,8 @@ int main(int argc, char *argv[]) &bglobal.bg_ev[3]); thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echo, &bglobal.bg_ev[4]); -#if 0 /* TODO VxLAN support. */ - thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_vxlan, + thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echov6, &bglobal.bg_ev[5]); -#endif thread_add_read(master, control_accept, NULL, bglobal.bg_csock, &bglobal.bg_csockev); diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index ae6081f01a..1c6d03195c 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -827,7 +827,7 @@ DEFPY(bfd_show_peers_counters, bfd_show_peers_counters_cmd, * Configuration rules: * * Single hop: - * peer + (optional vxlan or interface name) + * peer + (interface name) * * Multi hop: * peer + local + (optional vrf) @@ -896,23 +896,6 @@ static int bfd_configure_peer(struct bfd_peer_cfg *bpc, bool mhop, bpc->bpc_mhop = mhop; -#if 0 - /* Handle VxLAN configuration. */ - if (vxlan >= 0) { - if (vxlan > ((1 << 24) - 1)) { - snprintf(ebuf, ebuflen, "invalid VxLAN %d", vxlan); - return -1; - } - if (bpc->bpc_mhop) { - snprintf(ebuf, ebuflen, - "multihop doesn't accept VxLAN"); - return -1; - } - - bpc->bpc_vxlan = vxlan; - } -#endif /* VxLAN */ - /* Handle interface specification configuration. */ if (ifname) { if (bpc->bpc_mhop) { diff --git a/bfdd/bsd.c b/bfdd/bsd.c index 34a3a1a801..e0fb340e30 100644 --- a/bfdd/bsd.c +++ b/bfdd/bsd.c @@ -33,38 +33,8 @@ #include "bfd.h" /* - * Prototypes - */ -static const char *sockaddr_to_string(const void *sv, char *buf, size_t buflen); - -/* * Definitions. */ -static const char *sockaddr_to_string(const void *sv, char *buf, size_t buflen) -{ - const struct sockaddr *sa = sv; - const struct sockaddr_in *sin = sv; - const struct sockaddr_in6 *sin6 = sv; - int unknown = 1; - - switch (sa->sa_family) { - case AF_INET: - if (inet_ntop(AF_INET, &sin->sin_addr, buf, buflen) != NULL) - unknown = 0; - break; - - case AF_INET6: - if (inet_ntop(AF_INET6, &sin6->sin6_addr, buf, buflen) != NULL) - unknown = 0; - break; - } - if (unknown == 0) - return buf; - - snprintf(buf, buflen, "unknown (af=%d)", sa->sa_family); - return buf; -} - int ptm_bfd_fetch_ifindex(const char *ifname) { return if_nametoindex(ifname); @@ -129,133 +99,6 @@ void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen) __LINE__); } -int ptm_bfd_echo_sock_init(void) -{ - int s, ttl, yes = 1; - struct sockaddr_in sin; - - s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC); - if (s == -1) { - log_error("echo-socket: creation failed: %s", strerror(errno)); - return -1; - } - - memset(&sin, 0, sizeof(sin)); -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - /* OmniOS doesn't have this field, but uses this code. */ - sin.sin_len = sizeof(sin); -#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ - sin.sin_family = AF_INET; - sin.sin_port = htons(3785); - if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) { - log_error("echo-socket: bind failure: %s", strerror(errno)); - close(s); - return -1; - } - - if (setsockopt(s, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) == -1) { - log_error("echo-socket: setsockopt(IP_RECVTTL): %s", - strerror(errno)); - close(s); - return -1; - } - - ttl = BFD_TTL_VAL; - if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) { - log_error("echo-socket: setsockopt(IP_TTL): %s", - strerror(errno)); - close(s); - return -1; - } - - return s; -} - -ssize_t bsd_echo_sock_read(int sd, uint8_t *buf, ssize_t *buflen, - struct sockaddr_storage *ss, socklen_t *sslen, - uint8_t *ttl, uint32_t *id) -{ - struct cmsghdr *cmsg; - struct bfd_echo_pkt *bep; - ssize_t readlen; - struct iovec iov; - struct msghdr msg; - uint8_t msgctl[255]; - char errbuf[255]; - - /* Prepare socket read. */ - memset(ss, 0, sizeof(*ss)); - memset(&msg, 0, sizeof(msg)); - iov.iov_base = buf; - iov.iov_len = *buflen; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = msgctl; - msg.msg_controllen = sizeof(msgctl); - msg.msg_name = ss; - msg.msg_namelen = *sslen; - - /* Read the socket and treat errors. */ - readlen = recvmsg(sd, &msg, 0); - if (readlen == 0) { - log_error("%s: recvmsg: socket closed", __func__); - return -1; - } - if (readlen == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) - return -1; - - log_error("%s: recvmsg: (%d) %s", __func__, errno, - strerror(errno)); - return -1; - } - /* Short packet, better not risk reading it. */ - if (readlen < (ssize_t)sizeof(*bep)) { - log_warning("%s: short packet (%ld of %d) from %s", __func__, - readlen, sizeof(*bep), - sockaddr_to_string(ss, errbuf, sizeof(errbuf))); - return -1; - } - *buflen = readlen; - - /* Read TTL information. */ - *ttl = 0; - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level != IPPROTO_IP) - continue; - if (cmsg->cmsg_type != IP_RECVTTL) - continue; - - *ttl = *(uint8_t *)CMSG_DATA(cmsg); - break; - } - if (*ttl == 0) { - log_debug("%s: failed to read TTL", __func__); - return -1; - } - - /* Read my discriminator from BFD Echo packet. */ - bep = (struct bfd_echo_pkt *)buf; - *id = bep->my_discr; - if (*id == 0) { - log_debug("%s: invalid packet discriminator from: %s", __func__, - sockaddr_to_string(ss, errbuf, sizeof(errbuf))); - return -1; - } - - /* Set the returned sockaddr new length. */ - *sslen = msg.msg_namelen; - - return 0; -} - -int ptm_bfd_vxlan_sock_init(void) -{ - /* TODO: not supported yet. */ - return -1; -} - int bp_bind_dev(int sd, const char *dev) { /* @@ -266,25 +109,4 @@ int bp_bind_dev(int sd, const char *dev) return 0; } -uint16_t udp4_checksum(struct ip *ip, uint8_t *buf, int len) -{ - char *ptr; - struct udp_psuedo_header pudp_hdr; - uint16_t csum; - - pudp_hdr.saddr = ip->ip_src.s_addr; - pudp_hdr.daddr = ip->ip_dst.s_addr; - pudp_hdr.reserved = 0; - pudp_hdr.protocol = ip->ip_p; - pudp_hdr.len = htons(len); - - ptr = XMALLOC(MTYPE_BFDD_TMP, UDP_PSUEDO_HDR_LEN + len); - memcpy(ptr, &pudp_hdr, UDP_PSUEDO_HDR_LEN); - memcpy(ptr + UDP_PSUEDO_HDR_LEN, buf, len); - - csum = checksum((uint16_t *)ptr, UDP_PSUEDO_HDR_LEN + len); - XFREE(MTYPE_BFDD_TMP, ptr); - return csum; -} - #endif /* BFD_BSD */ diff --git a/bfdd/config.c b/bfdd/config.c index 0e0d8b7d70..06089780c6 100644 --- a/bfdd/config.c +++ b/bfdd/config.c @@ -218,10 +218,6 @@ static int parse_peer_config(struct json_object *jo, struct bfd_peer_cfg *bpc) } else { log_debug("\tlocal-interface: %s", sval); } - } else if (strcmp(key, "vxlan") == 0) { - bpc->bpc_vxlan = json_object_get_int64(jo_val); - bpc->bpc_has_vxlan = true; - log_debug("\tvxlan: %ld", bpc->bpc_vxlan); } else if (strcmp(key, "vrf-name") == 0) { bpc->bpc_has_vrfname = true; sval = json_object_get_string(jo_val); diff --git a/bfdd/event.c b/bfdd/event.c index ba12f5b4e8..63f64077eb 100644 --- a/bfdd/event.c +++ b/bfdd/event.c @@ -49,8 +49,7 @@ void bfd_recvtimer_update(struct bfd_session *bs) #endif /* BFD_EVENT_DEBUG */ /* Remove previous schedule if any. */ - if (bs->recvtimer_ev) - bfd_recvtimer_delete(bs); + bfd_recvtimer_delete(bs); thread_add_timer_tv(master, bfd_recvtimer_cb, bs, &tv, &bs->recvtimer_ev); @@ -70,8 +69,7 @@ void bfd_echo_recvtimer_update(struct bfd_session *bs) #endif /* BFD_EVENT_DEBUG */ /* Remove previous schedule if any. */ - if (bs->echo_recvtimer_ev) - bfd_echo_recvtimer_delete(bs); + bfd_echo_recvtimer_delete(bs); thread_add_timer_tv(master, bfd_echo_recvtimer_cb, bs, &tv, &bs->echo_recvtimer_ev); @@ -91,8 +89,7 @@ void bfd_xmttimer_update(struct bfd_session *bs, uint64_t jitter) #endif /* BFD_EVENT_DEBUG */ /* Remove previous schedule if any. */ - if (bs->xmttimer_ev) - bfd_xmttimer_delete(bs); + bfd_xmttimer_delete(bs); thread_add_timer_tv(master, bfd_xmt_cb, bs, &tv, &bs->xmttimer_ev); } @@ -111,8 +108,7 @@ void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter) #endif /* BFD_EVENT_DEBUG */ /* Remove previous schedule if any. */ - if (bs->echo_xmttimer_ev) - bfd_echo_xmttimer_delete(bs); + bfd_echo_xmttimer_delete(bs); thread_add_timer_tv(master, bfd_echo_xmt_cb, bs, &tv, &bs->echo_xmttimer_ev); @@ -120,36 +116,20 @@ void bfd_echo_xmttimer_update(struct bfd_session *bs, uint64_t jitter) void bfd_recvtimer_delete(struct bfd_session *bs) { - if (bs->recvtimer_ev == NULL) - return; - - thread_cancel(bs->recvtimer_ev); - bs->recvtimer_ev = NULL; + THREAD_OFF(bs->recvtimer_ev); } void bfd_echo_recvtimer_delete(struct bfd_session *bs) { - if (bs->echo_recvtimer_ev == NULL) - return; - - thread_cancel(bs->echo_recvtimer_ev); - bs->echo_recvtimer_ev = NULL; + THREAD_OFF(bs->echo_recvtimer_ev); } void bfd_xmttimer_delete(struct bfd_session *bs) { - if (bs->xmttimer_ev == NULL) - return; - - thread_cancel(bs->xmttimer_ev); - bs->xmttimer_ev = NULL; + THREAD_OFF(bs->xmttimer_ev); } void bfd_echo_xmttimer_delete(struct bfd_session *bs) { - if (bs->echo_xmttimer_ev == NULL) - return; - - thread_cancel(bs->echo_xmttimer_ev); - bs->echo_xmttimer_ev = NULL; + THREAD_OFF(bs->echo_xmttimer_ev); } diff --git a/bfdd/linux.c b/bfdd/linux.c index 5f24ef4d19..e260851ddb 100644 --- a/bfdd/linux.c +++ b/bfdd/linux.c @@ -23,49 +23,8 @@ #ifdef BFD_LINUX -/* XXX: fix compilation error on Ubuntu 16.04 or older. */ -#ifndef _UAPI_IPV6_H -#define _UAPI_IPV6_H -#endif /* _UAPI_IPV6_H */ - -#include <linux/filter.h> -#include <linux/if_packet.h> - -#include <netinet/if_ether.h> - -#include <net/if.h> -#include <sys/ioctl.h> - #include "bfd.h" -/* Berkeley Packet filter code to filter out BFD Echo packets. - * tcpdump -dd "(udp dst port 3785)" - */ -static struct sock_filter bfd_echo_filter[] = { - {0x28, 0, 0, 0x0000000c}, {0x15, 0, 4, 0x000086dd}, - {0x30, 0, 0, 0x00000014}, {0x15, 0, 11, 0x00000011}, - {0x28, 0, 0, 0x00000038}, {0x15, 8, 9, 0x00000ec9}, - {0x15, 0, 8, 0x00000800}, {0x30, 0, 0, 0x00000017}, - {0x15, 0, 6, 0x00000011}, {0x28, 0, 0, 0x00000014}, - {0x45, 4, 0, 0x00001fff}, {0xb1, 0, 0, 0x0000000e}, - {0x48, 0, 0, 0x00000010}, {0x15, 0, 1, 0x00000ec9}, - {0x6, 0, 0, 0x0000ffff}, {0x6, 0, 0, 0x00000000}, -}; - -/* Berkeley Packet filter code to filter out BFD vxlan packets. - * tcpdump -dd "(udp dst port 4789)" - */ -static struct sock_filter bfd_vxlan_filter[] = { - {0x28, 0, 0, 0x0000000c}, {0x15, 0, 4, 0x000086dd}, - {0x30, 0, 0, 0x00000014}, {0x15, 0, 11, 0x00000011}, - {0x28, 0, 0, 0x00000038}, {0x15, 8, 9, 0x000012b5}, - {0x15, 0, 8, 0x00000800}, {0x30, 0, 0, 0x00000017}, - {0x15, 0, 6, 0x00000011}, {0x28, 0, 0, 0x00000014}, - {0x45, 4, 0, 0x00001fff}, {0xb1, 0, 0, 0x0000000e}, - {0x48, 0, 0, 0x00000010}, {0x15, 0, 1, 0x000012b5}, - {0x6, 0, 0, 0x0000ffff}, {0x6, 0, 0, 0x00000000}, -}; - /* * Definitions. @@ -128,55 +87,6 @@ void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen) ifr.ifr_name, ifname); } -int ptm_bfd_echo_sock_init(void) -{ - int s; - struct sock_fprog bpf = {.len = sizeof(bfd_echo_filter) - / sizeof(bfd_echo_filter[0]), - .filter = bfd_echo_filter}; - - s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); - if (s == -1) { - log_error("echo-socket: creation failure: %s", strerror(errno)); - return -1; - } - - if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)) - == -1) { - log_error("echo-socket: setsockopt(SO_ATTACH_FILTER): %s", - strerror(errno)); - close(s); - return -1; - } - - return s; -} - -int ptm_bfd_vxlan_sock_init(void) -{ - int s; - struct sock_fprog bpf = {.len = sizeof(bfd_vxlan_filter) - / sizeof(bfd_vxlan_filter[0]), - .filter = bfd_vxlan_filter}; - - s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); - if (s == -1) { - log_error("vxlan-socket: creation failure: %s", - strerror(errno)); - return -1; - } - - if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)) - == -1) { - log_error("vxlan-socket: setsockopt(SO_ATTACH_FILTER): %s", - strerror(errno)); - close(s); - return -1; - } - - return s; -} - int bp_bind_dev(int sd __attribute__((__unused__)), const char *dev __attribute__((__unused__))) { @@ -197,25 +107,4 @@ int bp_bind_dev(int sd __attribute__((__unused__)), return 0; } -uint16_t udp4_checksum(struct iphdr *iph, uint8_t *buf, int len) -{ - char *ptr; - struct udp_psuedo_header pudp_hdr; - uint16_t csum; - - pudp_hdr.saddr = iph->saddr; - pudp_hdr.daddr = iph->daddr; - pudp_hdr.reserved = 0; - pudp_hdr.protocol = iph->protocol; - pudp_hdr.len = htons(len); - - ptr = XMALLOC(MTYPE_BFDD_TMP, UDP_PSUEDO_HDR_LEN + len); - memcpy(ptr, &pudp_hdr, UDP_PSUEDO_HDR_LEN); - memcpy(ptr + UDP_PSUEDO_HDR_LEN, buf, len); - - csum = checksum((uint16_t *)ptr, UDP_PSUEDO_HDR_LEN + len); - XFREE(MTYPE_BFDD_TMP, ptr); - return csum; -} - #endif /* BFD_LINUX */ diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 47dffd146a..663bc4894a 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -530,7 +530,7 @@ void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr) /* * bgp_bfd_show_info - Show the peer BFD information. */ -void bgp_bfd_show_info(struct vty *vty, struct peer *peer, uint8_t use_json, +void bgp_bfd_show_info(struct vty *vty, struct peer *peer, bool use_json, json_object *json_neigh) { bfd_show_info(vty, (struct bfd_info *)peer->bfd_info, diff --git a/bgpd/bgp_bfd.h b/bgpd/bgp_bfd.h index a3cfca9c0d..caa5651e3a 100644 --- a/bgpd/bgp_bfd.h +++ b/bgpd/bgp_bfd.h @@ -34,8 +34,8 @@ extern void bgp_bfd_deregister_peer(struct peer *peer); extern void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr); -extern void bgp_bfd_show_info(struct vty *vty, struct peer *peer, - uint8_t use_json, json_object *json_neigh); +extern void bgp_bfd_show_info(struct vty *vty, struct peer *peer, bool use_json, + json_object *json_neigh); extern int bgp_bfd_is_peer_multihop(struct peer *peer); diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index bce6056ded..071ee6b9c6 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -523,7 +523,7 @@ void bgp_config_write_damp(struct vty *vty) } static const char *bgp_get_reuse_time(unsigned int penalty, char *buf, - size_t len, uint8_t use_json, + size_t len, bool use_json, json_object *json) { time_t reuse_time = 0; @@ -641,7 +641,7 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_info *binfo, } const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_info *binfo, - char *timebuf, size_t len, uint8_t use_json, + char *timebuf, size_t len, bool use_json, json_object *json) { struct bgp_damp_info *bdi; diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h index d3b0ae42aa..8326bae697 100644 --- a/bgpd/bgp_damp.h +++ b/bgpd/bgp_damp.h @@ -140,9 +140,10 @@ extern int bgp_damp_decay(time_t, int); extern void bgp_config_write_damp(struct vty *); extern void bgp_damp_info_vty(struct vty *, struct bgp_info *, json_object *json_path); -extern const char *bgp_damp_reuse_time_vty(struct vty *, struct bgp_info *, - char *, size_t, uint8_t, - json_object *); +extern const char *bgp_damp_reuse_time_vty(struct vty *vty, + struct bgp_info *binfo, + char *timebuf, size_t len, + bool use_json, json_object *json); extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t); #endif /* _QUAGGA_BGP_DAMP_H */ diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 9e814516b7..a104a2e16d 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -543,7 +543,7 @@ static void evpn_convert_nexthop_to_ipv6(struct attr *attr) static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, struct prefix_evpn *p, struct in_addr remote_vtep_ip, int add, - uint8_t flags) + uint8_t flags, uint32_t seq) { struct stream *s; int ipa_len; @@ -579,19 +579,22 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, stream_put_in_addr(s, &remote_vtep_ip); /* TX flags - MAC sticky status and/or gateway mac */ - if (add) + /* Also TX the sequence number of the best route. */ + if (add) { stream_putc(s, flags); + stream_putl(s, seq); + } stream_putw_at(s, 0, stream_get_endp(s)); if (bgp_debug_zebra(NULL)) zlog_debug( - "Tx %s MACIP, VNI %u MAC %s IP %s (flags: 0x%x) remote VTEP %s", + "Tx %s MACIP, VNI %u MAC %s IP %s flags 0x%x seq %u remote VTEP %s", add ? "ADD" : "DEL", vpn->vni, prefix_mac2str(&p->prefix.macip_addr.mac, buf1, sizeof(buf1)), ipaddr2str(&p->prefix.macip_addr.ip, - buf3, sizeof(buf3)), flags, + buf3, sizeof(buf3)), flags, seq, inet_ntop(AF_INET, &remote_vtep_ip, buf2, sizeof(buf2))); @@ -875,13 +878,14 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr) /* Install EVPN route into zebra. */ static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn, struct prefix_evpn *p, - struct in_addr remote_vtep_ip, uint8_t flags) + struct in_addr remote_vtep_ip, uint8_t flags, + uint32_t seq) { int ret; if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip, - 1, flags); + 1, flags, seq); else ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 1); @@ -897,7 +901,7 @@ static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn, if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip, - 0, 0); + 0, 0, 0); else ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 0); @@ -1141,7 +1145,8 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, ret = evpn_zebra_install( bgp, vpn, (struct prefix_evpn *)&rn->p, - old_select->attr->nexthop, flags); + old_select->attr->nexthop, flags, + mac_mobility_seqnum(old_select->attr)); } UNSET_FLAG(old_select->flags, BGP_INFO_MULTIPATH_CHG); bgp_zebra_clear_route_change_flags(rn); @@ -1177,7 +1182,8 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); ret = evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p, - new_select->attr->nexthop, flags); + new_select->attr->nexthop, flags, + mac_mobility_seqnum(new_select->attr)); /* If an old best existed and it was a "local" route, the only * reason * it would be supplanted is due to MAC mobility procedures. So, @@ -1557,11 +1563,12 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, */ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, afi_t afi, safi_t safi, struct bgp_node *rn, - struct attr *attr, int add, int vni_table, - struct bgp_info **ri, uint8_t flags) + struct attr *attr, int add, + struct bgp_info **ri, uint8_t flags, + uint32_t seq) { struct bgp_info *tmp_ri; - struct bgp_info *local_ri, *remote_ri; + struct bgp_info *local_ri; struct attr *attr_new; mpls_label_t label[BGP_MAX_LABELS]; uint32_t num_labels = 1; @@ -1573,28 +1580,13 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, evp = (struct prefix_evpn *)&rn->p; memset(&label, 0, sizeof(label)); - /* See if this is an update of an existing route, or a new add. Also, - * identify if already known from remote, and if so, the one with the - * highest sequence number; this is only when adding to the VNI routing - * table. - */ - local_ri = remote_ri = NULL; + /* See if this is an update of an existing route, or a new add. */ + local_ri = NULL; for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) { if (tmp_ri->peer == bgp->peer_self && tmp_ri->type == ZEBRA_ROUTE_BGP && tmp_ri->sub_type == BGP_ROUTE_STATIC) local_ri = tmp_ri; - if (vni_table) { - if (tmp_ri->type == ZEBRA_ROUTE_BGP - && tmp_ri->sub_type == BGP_ROUTE_IMPORTED - && CHECK_FLAG(tmp_ri->flags, BGP_INFO_VALID)) { - if (!remote_ri) - remote_ri = tmp_ri; - else if (mac_mobility_seqnum(tmp_ri->attr) - > mac_mobility_seqnum(remote_ri->attr)) - remote_ri = tmp_ri; - } - } } /* If route doesn't exist already, create a new one, if told to. @@ -1604,22 +1596,11 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, if (!local_ri && !add) return 0; - if (!local_ri) { - /* When learnt locally for the first time but already known from - * remote, we have to initiate appropriate MAC mobility steps. - * This is applicable when updating the VNI routing table. - * We need to skip mobility steps for g/w macs (local mac on g/w - * SVI) advertised in EVPN. - * This will ensure that local routes are preferred for g/w macs - */ - if (remote_ri && !CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) { - uint32_t cur_seqnum; - - /* Add MM extended community to route. */ - cur_seqnum = mac_mobility_seqnum(remote_ri->attr); - add_mac_mobility_to_attr(cur_seqnum + 1, attr); - } + /* For non-GW MACs, update MAC mobility seq number, if needed. */ + if (seq && !CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) + add_mac_mobility_to_attr(seq, attr); + if (!local_ri) { /* Add (or update) attribute to hash. */ attr_new = bgp_attr_intern(attr); @@ -1685,6 +1666,11 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, attr_new = bgp_attr_intern(attr); bgp_info_set_flag(rn, tmp_ri, BGP_INFO_ATTR_CHANGED); + /* Extract MAC mobility sequence number, if any. */ + attr_new->mm_seqnum = + bgp_attr_mac_mobility_seqnum(attr_new, &sticky); + attr_new->sticky = sticky; + /* Restore route, if needed. */ if (CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED)) bgp_info_restore(rn, tmp_ri); @@ -1706,7 +1692,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, * and schedule for processing. */ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, - struct prefix_evpn *p, uint8_t flags) + struct prefix_evpn *p, uint8_t flags, + uint32_t seq) { struct bgp_node *rn; struct attr attr; @@ -1758,7 +1745,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, /* Create or update route entry. */ route_change = update_evpn_route_entry(bgp, vpn, afi, safi, rn, &attr, - 1, 1, &ri, flags); + 1, &ri, flags, seq); assert(ri); attr_new = ri->attr; @@ -1778,8 +1765,8 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, (struct prefix *)p, &vpn->prd); - update_evpn_route_entry(bgp, vpn, afi, safi, rn, attr_new, 1, 0, - &global_ri, flags); + update_evpn_route_entry(bgp, vpn, afi, safi, rn, attr_new, 1, + &global_ri, flags, seq); /* Schedule for processing and unlock node. */ bgp_process(bgp, rn, afi, safi); @@ -1954,58 +1941,14 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) afi_t afi; safi_t safi; struct bgp_node *rn; - struct bgp_info *ri; + struct bgp_info *ri, *tmp_ri; struct attr attr; - struct attr attr_sticky; - struct attr attr_def_gw; - struct attr attr_ip6_ll; struct attr *attr_new; + uint32_t seq; int add_l3_ecomm = 0; afi = AFI_L2VPN; safi = SAFI_EVPN; - memset(&attr, 0, sizeof(struct attr)); - memset(&attr_sticky, 0, sizeof(struct attr)); - memset(&attr_def_gw, 0, sizeof(struct attr)); - memset(&attr_ip6_ll, 0, sizeof(struct attr)); - - /* Build path-attribute - multiple type-2 routes for this VNI will share - * the same path attribute, but we need separate structures for sticky - * MACs, default gateway and IPv6 link-local addresses (no L3 RT/RMAC). - */ - bgp_attr_default_set(&attr, BGP_ORIGIN_IGP); - bgp_attr_default_set(&attr_sticky, BGP_ORIGIN_IGP); - bgp_attr_default_set(&attr_def_gw, BGP_ORIGIN_IGP); - attr.nexthop = vpn->originator_ip; - attr.mp_nexthop_global_in = vpn->originator_ip; - attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - bgpevpn_get_rmac(vpn, &attr.rmac); - attr_sticky.nexthop = vpn->originator_ip; - attr_sticky.mp_nexthop_global_in = vpn->originator_ip; - attr_sticky.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - attr_sticky.sticky = 1; - bgpevpn_get_rmac(vpn, &attr_sticky.rmac); - attr_def_gw.nexthop = vpn->originator_ip; - attr_def_gw.mp_nexthop_global_in = vpn->originator_ip; - attr_def_gw.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - attr_def_gw.default_gw = 1; - bgpevpn_get_rmac(vpn, &attr_def_gw.rmac); - bgp_attr_default_set(&attr_ip6_ll, BGP_ORIGIN_IGP); - attr_ip6_ll.nexthop = vpn->originator_ip; - attr_ip6_ll.mp_nexthop_global_in = vpn->originator_ip; - attr_ip6_ll.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - - /* Add L3 VNI RTs and RMAC for non IPv6 link-local attributes if - * using L3 VNI for type-2 routes also. - */ - if (CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS) && - bgpevpn_get_l3vni(vpn)) - add_l3_ecomm = 1; - - build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm); - build_evpn_route_extcomm(vpn, &attr_sticky, add_l3_ecomm); - build_evpn_route_extcomm(vpn, &attr_def_gw, add_l3_ecomm); - build_evpn_route_extcomm(vpn, &attr_ip6_ll, 0); /* Walk this VNI's route table and update local type-2 routes. For any * routes updated, update corresponding entry in the global table too. @@ -2019,35 +1962,57 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE) continue; - if (is_evpn_prefix_ipaddr_v6(evp) && - IN6_IS_ADDR_LINKLOCAL(&evp->prefix.macip_addr.ip.ipaddr_v6)) - update_evpn_route_entry(bgp, vpn, afi, safi, rn, - &attr_ip6_ll, 0, 1, &ri, 0); - else { - if (evpn_route_is_sticky(bgp, rn)) - update_evpn_route_entry(bgp, vpn, afi, safi, rn, - &attr_sticky, 0, 1, &ri, - 0); - else if (evpn_route_is_def_gw(bgp, rn)) { - if (is_evpn_prefix_ipaddr_v6(evp)) - attr_def_gw.router_flag = 1; - update_evpn_route_entry(bgp, vpn, afi, safi, rn, - &attr_def_gw, 0, 1, &ri, - 0); - } else - update_evpn_route_entry(bgp, vpn, afi, safi, rn, - &attr, 0, 1, &ri, 0); + /* Identify local route. */ + for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) { + if (tmp_ri->peer == bgp->peer_self + && tmp_ri->type == ZEBRA_ROUTE_BGP + && tmp_ri->sub_type == BGP_ROUTE_STATIC) + break; } - /* If a local route exists for this prefix, we need to update - * the global routing table too. - */ - if (!ri) + if (!tmp_ri) continue; + /* + * Build attribute per local route as the MAC mobility and + * some other values could differ for different routes. The + * attributes will be shared in the hash table. + */ + bgp_attr_default_set(&attr, BGP_ORIGIN_IGP); + attr.nexthop = vpn->originator_ip; + attr.mp_nexthop_global_in = vpn->originator_ip; + attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; + bgpevpn_get_rmac(vpn, &attr.rmac); + + if (evpn_route_is_sticky(bgp, rn)) + attr.sticky = 1; + else if (evpn_route_is_def_gw(bgp, rn)) { + attr.default_gw = 1; + if (is_evpn_prefix_ipaddr_v6(evp)) + attr.router_flag = 1; + } + + /* Add L3 VNI RTs and RMAC for non IPv6 link-local if + * using L3 VNI for type-2 routes also. + */ + if ((is_evpn_prefix_ipaddr_v4(evp) || + !IN6_IS_ADDR_LINKLOCAL( + &evp->prefix.macip_addr.ip.ipaddr_v6)) && + CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS) && + bgpevpn_get_l3vni(vpn)) + add_l3_ecomm = 1; + + /* Set up extended community. */ + build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm); + + seq = mac_mobility_seqnum(tmp_ri->attr); + + /* Update the route entry. */ + update_evpn_route_entry(bgp, vpn, afi, safi, rn, + &attr, 0, &ri, 0, seq); + /* Perform route selection; this is just to set the flags - * correctly - * as local route in the VNI always wins. + * correctly as local route in the VNI always wins. */ evpn_route_select_install(bgp, vpn, rn); @@ -2058,18 +2023,17 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) (struct prefix *)evp, &vpn->prd); assert(rd_rn); update_evpn_route_entry(bgp, vpn, afi, safi, rd_rn, attr_new, 0, - 0, &global_ri, 0); + &global_ri, 0, + mac_mobility_seqnum(attr_new)); /* Schedule for processing and unlock node. */ bgp_process(bgp, rd_rn, afi, safi); bgp_unlock_node(rd_rn); - } - /* Unintern temporary. */ - aspath_unintern(&attr.aspath); - aspath_unintern(&attr_sticky.aspath); - aspath_unintern(&attr_def_gw.aspath); - aspath_unintern(&attr_ip6_ll.aspath); + /* Unintern temporary. */ + aspath_unintern(&attr.aspath); + + } return 0; } @@ -2206,7 +2170,7 @@ static int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) * locally learnt type-2 routes (MACIP) - for this VNI. */ build_evpn_type3_prefix(&p, vpn->originator_ip); - ret = update_evpn_route(bgp, vpn, &p, 0); + ret = update_evpn_route(bgp, vpn, &p, 0, 0); if (ret) return ret; @@ -3451,8 +3415,8 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, (struct prefix *)&p, &vpn->prd); - update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, 0, &ri, - 0); + update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, &ri, + 0, mac_mobility_seqnum(attr)); /* Schedule for processing and unlock node. */ bgp_process(bgp, global_rn, afi, safi); @@ -3485,7 +3449,8 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) (struct prefix *)evp, &vpn->prd); assert(global_rn); update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, - 0, &global_ri, 0); + &global_ri, 0, + mac_mobility_seqnum(attr)); /* Schedule for processing and unlock node. */ bgp_process(bgp, global_rn, afi, safi); @@ -5213,7 +5178,7 @@ int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac, * Handle add of a local MACIP. */ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac, - struct ipaddr *ip, uint8_t flags) + struct ipaddr *ip, uint8_t flags, uint32_t seq) { struct bgpevpn *vpn; struct prefix_evpn p; @@ -5228,7 +5193,7 @@ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac, /* Create EVPN type-2 route and schedule for processing. */ build_evpn_type2_prefix(&p, mac, ip); - if (update_evpn_route(bgp, vpn, &p, flags)) { + if (update_evpn_route(bgp, vpn, &p, flags, seq)) { char buf[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; @@ -5525,7 +5490,7 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, /* Create EVPN type-3 route and schedule for processing. */ build_evpn_type3_prefix(&p, vpn->originator_ip); - if (update_evpn_route(bgp, vpn, &p, 0)) { + if (update_evpn_route(bgp, vpn, &p, 0, 0)) { flog_err(BGP_ERR_EVPN_ROUTE_CREATE, "%u: Type3 route creation failure for VNI %u", bgp->vrf_id, vni); diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 91d4c9fac4..b002be3d3d 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -132,7 +132,7 @@ extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac, struct ipaddr *ip); extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac, struct ipaddr *ip, - uint8_t flags); + uint8_t flags, uint32_t seq); extern int bgp_evpn_local_l3vni_add(vni_t vni, vrf_id_t vrf_id, struct ethaddr *rmac, struct in_addr originator_ip, int filter); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index b553cb42a5..a6cc2d9b53 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -983,7 +983,7 @@ static void show_vni_entry(struct hash_backet *backet, void *args[]) static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type, void *output_arg, - int option, uint8_t use_json) + int option, bool use_json) { afi_t afi = AFI_L2VPN; struct bgp *bgp; @@ -1276,7 +1276,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_routes, union sockunion su; struct peer *peer; int ret; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); argv_find(argv, argc, "A.B.C.D", &idx_ipv4); @@ -1336,7 +1336,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes, union sockunion su; struct peer *peer; struct prefix_rd prd; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community); argv_find(argv, argc, "A.B.C.D", &idx_ipv4); @@ -1409,7 +1409,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes, int ret; struct peer *peer; union sockunion su; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); argv_find(argv, argc, "A.B.C.D", &idx_ipv4); @@ -1467,7 +1467,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes, struct peer *peer; struct prefix_rd prd; union sockunion su; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community); argv_find(argv, argc, "A.B.C.D", &idx_ipv4); @@ -3172,7 +3172,7 @@ DEFUN(show_bgp_l2vpn_evpn_vni, struct bgp *bgp_def; vni_t vni; int idx = 0; - uint8_t uj = 0; + bool uj = false; json_object *json = NULL; uint32_t num_l2vnis = 0; uint32_t num_l3vnis = 0; @@ -3255,7 +3255,7 @@ DEFUN(show_bgp_l2vpn_evpn_es, JSON_STR) { int idx = 0; - uint8_t uj = 0; + bool uj = false; esi_t esi; json_object *json = NULL; struct bgp *bgp = NULL; @@ -3312,7 +3312,7 @@ DEFUN(show_bgp_l2vpn_evpn_summary, JSON_STR) { int idx_vrf = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); char *vrf = NULL; if (argv_find(argv, argc, "vrf", &idx_vrf)) @@ -3341,7 +3341,7 @@ DEFUN(show_bgp_l2vpn_evpn_route, struct bgp *bgp; int type_idx = 0; int type = 0; - uint8_t uj = 0; + bool uj = false; json_object *json = NULL; uj = use_json(argc, argv); @@ -3404,7 +3404,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd, int type = 0; int rd_idx = 0; int type_idx = 0; - int uj = 0; + bool uj = false; json_object *json = NULL; bgp = bgp_get_default(); @@ -3477,7 +3477,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd_macip, int rd_idx = 0; int mac_idx = 0; int ip_idx = 0; - int uj = 0; + bool uj = false; json_object *json = NULL; memset(&mac, 0, sizeof(struct ethaddr)); @@ -3541,7 +3541,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_esi, "ESI ID\n" JSON_STR) { - int uj = 0; + bool uj = false; esi_t esi; struct bgp *bgp = NULL; json_object *json = NULL; @@ -3597,7 +3597,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd, struct in_addr vtep_ip; int type = 0; int idx = 0; - int uj = 0; + bool uj = false; json_object *json = NULL; bgp = bgp_get_default(); @@ -3669,7 +3669,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_macip, struct ethaddr mac; struct ipaddr ip; int idx = 0; - int uj = 0; + bool uj = false; json_object *json = NULL; bgp = bgp_get_default(); @@ -3737,7 +3737,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast, int ret; struct in_addr orig_ip; int idx = 0; - int uj = 0; + bool uj = false; json_object *json = NULL; bgp = bgp_get_default(); @@ -3793,7 +3793,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_all, struct bgp *bgp; struct in_addr vtep_ip; int idx = 0; - int uj = 0; + bool uj = false; json_object *json = NULL; bgp = bgp_get_default(); @@ -3841,7 +3841,7 @@ DEFUN(show_bgp_l2vpn_evpn_vrf_import_rt, "Show vrf import route target\n" JSON_STR) { - uint8_t uj = 0; + bool uj = false; struct bgp *bgp_def = NULL; json_object *json = NULL; @@ -3878,7 +3878,7 @@ DEFUN(show_bgp_l2vpn_evpn_import_rt, JSON_STR) { struct bgp *bgp; - uint8_t uj = 0; + bool uj = false; json_object *json = NULL; bgp = bgp_get_default(); @@ -4359,7 +4359,7 @@ DEFUN (show_bgp_vrf_l3vni_info, json_object *json_vnis = NULL; json_object *json_export_rts = NULL; json_object *json_import_rts = NULL; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (uj) { json = json_object_new_object(); diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c index ae9d805b05..c7977a9af4 100644 --- a/bgpd/bgp_filter.c +++ b/bgpd/bgp_filter.c @@ -391,16 +391,25 @@ static int as_list_dup_check(struct as_list *aslist, struct as_filter *new) return 0; } -DEFUN (ip_as_path, - ip_as_path_cmd, - "ip as-path access-list WORD <deny|permit> LINE...", - IP_STR - "BGP autonomous system path filter\n" - "Specify an access list name\n" - "Regular expression access list name\n" - "Specify packets to reject\n" - "Specify packets to forward\n" - "A regular-expression to match the BGP AS paths\n") +static int config_bgp_aspath_validate(const char *regstr) +{ + char valid_chars[] = "1234567890_^|[,{}() ]$*+.?-"; + + if (strspn(regstr, valid_chars) == strlen(regstr)) + return 1; + + return 0; +} + +DEFUN(ip_as_path, ip_as_path_cmd, + "ip as-path access-list WORD <deny|permit> LINE...", + IP_STR + "BGP autonomous system path filter\n" + "Specify an access list name\n" + "Regular expression access list name\n" + "Specify packets to reject\n" + "Specify packets to forward\n" + "A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n") { int idx = 0; enum as_filter_type type; @@ -428,6 +437,12 @@ DEFUN (ip_as_path, return CMD_WARNING_CONFIG_FAILED; } + if (!config_bgp_aspath_validate(regstr)) { + vty_out(vty, "Invalid character in as-path access-list %s\n", + regstr); + return CMD_WARNING_CONFIG_FAILED; + } + asfilter = as_filter_make(regex, regstr, type); XFREE(MTYPE_TMP, regstr); @@ -444,17 +459,15 @@ DEFUN (ip_as_path, return CMD_SUCCESS; } -DEFUN (no_ip_as_path, - no_ip_as_path_cmd, - "no ip as-path access-list WORD <deny|permit> LINE...", - NO_STR - IP_STR - "BGP autonomous system path filter\n" - "Specify an access list name\n" - "Regular expression access list name\n" - "Specify packets to reject\n" - "Specify packets to forward\n" - "A regular-expression to match the BGP AS paths\n") +DEFUN(no_ip_as_path, no_ip_as_path_cmd, + "no ip as-path access-list WORD <deny|permit> LINE...", + NO_STR IP_STR + "BGP autonomous system path filter\n" + "Specify an access list name\n" + "Regular expression access list name\n" + "Specify packets to reject\n" + "Specify packets to forward\n" + "A regular-expression (1234567890_(^|[,{}() ]|$)) to match the BGP AS paths\n") { int idx = 0; enum as_filter_type type; @@ -488,6 +501,12 @@ DEFUN (no_ip_as_path, argv_find(argv, argc, "LINE", &idx); regstr = argv_concat(argv, argc, idx); + if (!config_bgp_aspath_validate(regstr)) { + vty_out(vty, "Invalid character in as-path access-list %s\n", + regstr); + return CMD_WARNING_CONFIG_FAILED; + } + regex = bgp_regcomp(regstr); if (!regex) { vty_out(vty, "can't compile regexp %s\n", regstr); diff --git a/bgpd/bgp_flowspec.h b/bgpd/bgp_flowspec.h index 9f69dbedda..f07b696b8d 100644 --- a/bgpd/bgp_flowspec.h +++ b/bgpd/bgp_flowspec.h @@ -34,9 +34,8 @@ extern void bgp_flowspec_vty_init(void); extern int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi, struct bgp_table *table, - enum bgp_show_type type, - void *output_arg, uint8_t use_json, - int is_last, + enum bgp_show_type type, void *output_arg, + bool use_json, int is_last, unsigned long *output_cum, unsigned long *total_cum); @@ -50,12 +49,10 @@ extern void route_vty_out_flowspec(struct vty *vty, struct prefix *p, extern int bgp_fs_config_write_pbr(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi); -extern int bgp_flowspec_display_match_per_ip(afi_t afi, - struct bgp_table *rib, - struct prefix *match, - int prefix_check, - struct vty *vty, - uint8_t use_json, - json_object *json_paths); +extern int bgp_flowspec_display_match_per_ip(afi_t afi, struct bgp_table *rib, + struct prefix *match, + int prefix_check, struct vty *vty, + bool use_json, + json_object *json_paths); #endif /* _FRR_BGP_FLOWSPEC_H */ diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index 31d2c540fa..978ce6bf4e 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -365,9 +365,8 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p, int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi, struct bgp_table *table, enum bgp_show_type type, - void *output_arg, uint8_t use_json, - int is_last, unsigned long *output_cum, - unsigned long *total_cum) + void *output_arg, bool use_json, int is_last, + unsigned long *output_cum, unsigned long *total_cum) { struct bgp_info *ri; struct bgp_node *rn; @@ -527,13 +526,11 @@ DEFUN (bgp_fs_local_install_ifname, return bgp_fs_local_install_interface(bgp, no, ifname); } -extern int bgp_flowspec_display_match_per_ip(afi_t afi, - struct bgp_table *rib, - struct prefix *match, - int prefix_check, - struct vty *vty, - uint8_t use_json, - json_object *json_paths) +extern int bgp_flowspec_display_match_per_ip(afi_t afi, struct bgp_table *rib, + struct prefix *match, + int prefix_check, struct vty *vty, + bool use_json, + json_object *json_paths) { struct bgp_node *rn; struct prefix *prefix; diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index b89edfe459..459775c8ec 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -1775,7 +1775,7 @@ DEFUN (no_vpnv6_network, int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd, enum bgp_show_type type, void *output_arg, int tags, - uint8_t use_json) + bool use_json) { struct bgp *bgp; struct bgp_table *table; @@ -1953,7 +1953,7 @@ DEFUN (show_ip_bgp_vpn_all_neighbor_routes, union sockunion su; struct peer *peer; int ret; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); afi_t afi; int idx = 0; @@ -2017,7 +2017,7 @@ DEFUN (show_ip_bgp_vpn_rd_neighbor_routes, union sockunion su; struct peer *peer; struct prefix_rd prd; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); afi_t afi; int idx = 0; @@ -2095,7 +2095,7 @@ DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes, int ret; struct peer *peer; union sockunion su; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); afi_t afi; int idx = 0; @@ -2157,7 +2157,7 @@ DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes, struct peer *peer; struct prefix_rd prd; union sockunion su; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); afi_t afi; int idx = 0; diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 122ae9e905..61b87392a2 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -50,7 +50,7 @@ extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *afi); extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd, enum bgp_show_type type, void *output_arg, - int tags, uint8_t use_json); + int tags, bool use_json); extern void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, struct bgp *bgp_vrf, struct bgp_info *info_vrf); diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 7fbc030242..5bdee5f512 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -52,8 +52,8 @@ Next, if we send capability to the peer we want to set my capabilty inforation at each peer. */ -void bgp_capability_vty_out(struct vty *vty, struct peer *peer, - uint8_t use_json, json_object *json_neigh) +void bgp_capability_vty_out(struct vty *vty, struct peer *peer, bool use_json, + json_object *json_neigh) { char *pnt; char *end; diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h index 42ebe97f2e..0fc321bdf3 100644 --- a/bgpd/bgp_open.h +++ b/bgpd/bgp_open.h @@ -86,8 +86,8 @@ struct graceful_restart_af { extern int bgp_open_option_parse(struct peer *, uint8_t, int *); extern void bgp_open_capability(struct stream *, struct peer *); -extern void bgp_capability_vty_out(struct vty *, struct peer *, uint8_t, - json_object *); +extern void bgp_capability_vty_out(struct vty *vty, struct peer *peer, + bool use_json, json_object *json_neigh); extern as_t peek_for_as4_capability(struct peer *, uint8_t); #endif /* _QUAGGA_BGP_OPEN_H */ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 50c484d7de..32506623c7 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -6755,7 +6755,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, /* called from terminal list command */ void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr, - safi_t safi, uint8_t use_json, json_object *json_ar) + safi_t safi, bool use_json, json_object *json_ar) { json_object *json_status = NULL; json_object *json_net = NULL; @@ -7084,7 +7084,7 @@ void route_vty_out_overlay(struct vty *vty, struct prefix *p, /* dampening route */ static void damp_route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, int display, safi_t safi, - uint8_t use_json, json_object *json) + bool use_json, json_object *json) { struct attr *attr; int len; @@ -7147,7 +7147,7 @@ static void damp_route_vty_out(struct vty *vty, struct prefix *p, /* flap route */ static void flap_route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, int display, safi_t safi, - uint8_t use_json, json_object *json) + bool use_json, json_object *json) { struct attr *attr; struct bgp_damp_info *bdi; @@ -8160,12 +8160,12 @@ static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr, afi_t afi, safi_t safi, enum bgp_show_type type); static int bgp_show_community(struct vty *vty, struct bgp *bgp, const char *comstr, int exact, afi_t afi, - safi_t safi, uint8_t use_json); + safi_t safi, bool use_json); static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_table *table, enum bgp_show_type type, - void *output_arg, uint8_t use_json, char *rd, + void *output_arg, bool use_json, char *rd, int is_last, unsigned long *output_cum, unsigned long *total_cum, unsigned long *json_header_depth) @@ -8452,8 +8452,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_table *table, struct prefix_rd *prd_match, - enum bgp_show_type type, void *output_arg, - uint8_t use_json) + enum bgp_show_type type, void *output_arg, bool use_json) { struct bgp_node *rn, *next; unsigned long output_cum = 0; @@ -8493,7 +8492,7 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, return CMD_SUCCESS; } static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, - enum bgp_show_type type, void *output_arg, uint8_t use_json) + enum bgp_show_type type, void *output_arg, bool use_json) { struct bgp_table *table; unsigned long json_header_depth = 0; @@ -8531,16 +8530,18 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, } static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, - safi_t safi, uint8_t use_json) + safi_t safi, bool use_json) { struct listnode *node, *nnode; struct bgp *bgp; int is_first = 1; + bool route_output = false; if (use_json) vty_out(vty, "{\n"); for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + route_output = true; if (use_json) { if (!is_first) vty_out(vty, ",\n"); @@ -8563,6 +8564,8 @@ static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, if (use_json) vty_out(vty, "}\n"); + else if (!route_output) + vty_out(vty, "%% BGP instance not found\n"); } /* Header of detailed BGP route information */ @@ -8748,8 +8751,7 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp, struct bgp_table *rib, const char *ip_str, afi_t afi, safi_t safi, struct prefix_rd *prd, int prefix_check, - enum bgp_path_type pathtype, - uint8_t use_json) + enum bgp_path_type pathtype, bool use_json) { int ret; int header; @@ -8885,7 +8887,7 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp, static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str, afi_t afi, safi_t safi, struct prefix_rd *prd, int prefix_check, enum bgp_path_type pathtype, - uint8_t use_json) + bool use_json) { if (!bgp) { bgp = bgp_get_default(); @@ -8909,7 +8911,7 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str, static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc, struct cmd_token **argv, afi_t afi, safi_t safi, - uint8_t uj) + bool uj) { struct lcommunity *lcom; struct buffer *b; @@ -8946,7 +8948,7 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc, static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp, const char *lcom, afi_t afi, safi_t safi, - uint8_t uj) + bool uj) { struct community_list *list; @@ -8994,7 +8996,7 @@ DEFUN (show_ip_bgp_large_community_list, safi = bgp_vty_safi_from_str(argv[idx]->text); } - int uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct bgp *bgp = bgp_lookup_by_name(vrf); if (bgp == NULL) { @@ -9037,7 +9039,7 @@ DEFUN (show_ip_bgp_large_community, safi = bgp_vty_safi_from_str(argv[idx]->text); } - int uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct bgp *bgp = bgp_lookup_by_name(vrf); if (bgp == NULL) { @@ -9121,7 +9123,7 @@ DEFUN (show_ip_bgp, int idx = 0; bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp); + &bgp, false); if (!idx) return CMD_WARNING; @@ -9197,16 +9199,16 @@ DEFUN (show_ip_bgp_json, int idx = 0; int idx_community_type = 0; int exact_match = 0; + bool uj = use_json(argc, argv); + + if (uj) + argc--; bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp); + &bgp, uj); if (!idx) return CMD_WARNING; - int uj = use_json(argc, argv); - if (uj) - argc--; - if (argv_find(argv, argc, "cidr-only", &idx)) return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only, NULL, uj); @@ -9275,12 +9277,12 @@ DEFUN (show_ip_bgp_route, char *prefix = NULL; struct bgp *bgp = NULL; enum bgp_path_type path_type; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); int idx = 0; bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp); + &bgp, uj); if (!idx) return CMD_WARNING; @@ -9343,7 +9345,7 @@ DEFUN (show_ip_bgp_regexp, int idx = 0; bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp); + &bgp, false); if (!idx) return CMD_WARNING; @@ -9372,17 +9374,17 @@ DEFUN (show_ip_bgp_instance_all, afi_t afi = AFI_IP; safi_t safi = SAFI_UNICAST; struct bgp *bgp = NULL; - int idx = 0; - bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp); - if (!idx) - return CMD_WARNING; + bool uj = use_json(argc, argv); - int uj = use_json(argc, argv); if (uj) argc--; + bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, + &bgp, uj); + if (!idx) + return CMD_WARNING; + bgp_show_all_instances_routes_vty(vty, afi, safi, uj); return CMD_SUCCESS; } @@ -9453,7 +9455,7 @@ static int bgp_show_route_map(struct vty *vty, struct bgp *bgp, static int bgp_show_community(struct vty *vty, struct bgp *bgp, const char *comstr, int exact, afi_t afi, - safi_t safi, uint8_t use_json) + safi_t safi, bool use_json) { struct community *com; int ret = 0; @@ -9512,7 +9514,7 @@ static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp, } static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, - const char *ip_str, uint8_t use_json) + const char *ip_str, bool use_json) { int ret; struct peer *peer; @@ -9899,7 +9901,7 @@ static int bgp_peer_count_walker(struct thread *t) } static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi, - safi_t safi, uint8_t use_json) + safi_t safi, bool use_json) { struct peer_pcounts pcounts = {.peer = peer}; unsigned int i; @@ -10009,16 +10011,16 @@ DEFUN (show_ip_bgp_instance_neighbor_prefix_counts, struct peer *peer; int idx = 0; struct bgp *bgp = NULL; + bool uj = use_json(argc, argv); + + if (uj) + argc--; bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp); + &bgp, uj); if (!idx) return CMD_WARNING; - int uj = use_json(argc, argv); - if (uj) - argc--; - argv_find(argv, argc, "neighbors", &idx); peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj); if (!peer) @@ -10045,7 +10047,7 @@ DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts, { int idx_peer = 6; struct peer *peer; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj); if (!peer) @@ -10118,7 +10120,7 @@ DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix, static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, enum bgp_show_adj_route_type type, - const char *rmap_name, uint8_t use_json, + const char *rmap_name, bool use_json, json_object *json) { struct bgp_table *table; @@ -10389,7 +10391,7 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, enum bgp_show_adj_route_type type, - const char *rmap_name, uint8_t use_json) + const char *rmap_name, bool use_json) { json_object *json = NULL; @@ -10463,18 +10465,17 @@ DEFUN (show_ip_bgp_instance_neighbor_advertised_route, struct bgp *bgp = NULL; struct peer *peer; enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised; - int idx = 0; - bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp); - if (!idx) - return CMD_WARNING; - - int uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (uj) argc--; + bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, + &bgp, uj); + if (!idx) + return CMD_WARNING; + /* neighbors <A.B.C.D|X:X::X:X|WORD> */ argv_find(argv, argc, "neighbors", &idx); peerstr = argv[++idx]->arg; @@ -10536,7 +10537,7 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter, argv_find(argv, argc, "neighbors", &idx); peerstr = argv[++idx]->arg; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); ret = str2sockunion(peerstr, &su); if (ret < 0) { @@ -10580,7 +10581,7 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter, static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, - enum bgp_show_type type, uint8_t use_json) + enum bgp_show_type type, bool use_json) { /* labeled-unicast routes live in the unicast table */ if (safi == SAFI_LABELED_UNICAST) @@ -10620,14 +10621,17 @@ DEFUN (show_ip_bgp_flowspec_routes_detailed, safi_t safi = SAFI_UNICAST; struct bgp *bgp = NULL; int idx = 0; + bool uj = use_json(argc, argv); + + if (uj) + argc--; bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp); + &bgp, uj); if (!idx) return CMD_WARNING; - return bgp_show(vty, bgp, afi, safi, - bgp_show_type_detail, NULL, use_json(argc, argv)); + return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj); } DEFUN (show_ip_bgp_neighbor_routes, @@ -10655,18 +10659,17 @@ DEFUN (show_ip_bgp_neighbor_routes, safi_t safi = SAFI_UNICAST; struct peer *peer; enum bgp_show_type sh_type = bgp_show_type_neighbor; - int idx = 0; + bool uj = use_json(argc, argv); + + if (uj) + argc--; bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp); + &bgp, uj); if (!idx) return CMD_WARNING; - int uj = use_json(argc, argv); - if (uj) - argc--; - /* neighbors <A.B.C.D|X:X::X:X|WORD> */ argv_find(argv, argc, "neighbors", &idx); peerstr = argv[++idx]->arg; diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index dfef9a8f79..476bb3aa05 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -435,8 +435,9 @@ extern void route_vty_out(struct vty *, struct prefix *, struct bgp_info *, int, safi_t, json_object *); extern void route_vty_out_tag(struct vty *, struct prefix *, struct bgp_info *, int, safi_t, json_object *); -extern void route_vty_out_tmp(struct vty *, struct prefix *, struct attr *, - safi_t, uint8_t, json_object *); +extern void route_vty_out_tmp(struct vty *vty, struct prefix *p, + struct attr *attr, safi_t safi, bool use_json, + json_object *json_ar); extern void route_vty_out_overlay(struct vty *vty, struct prefix *p, struct bgp_info *binfo, int display, json_object *json); @@ -484,5 +485,5 @@ extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp, extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_table *table, struct prefix_rd *prd, enum bgp_show_type type, void *output_arg, - uint8_t use_json); + bool use_json); #endif /* _QUAGGA_BGP_ROUTE_H */ diff --git a/bgpd/bgp_vpn.c b/bgpd/bgp_vpn.c index a771eedf0f..2b4477ddde 100644 --- a/bgpd/bgp_vpn.c +++ b/bgpd/bgp_vpn.c @@ -32,7 +32,7 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, struct prefix_rd *prd, afi_t afi, safi_t safi, - uint8_t use_json) + bool use_json) { struct bgp *bgp; struct bgp_table *table; diff --git a/bgpd/bgp_vpn.h b/bgpd/bgp_vpn.h index 98b4d9f180..a2e86476a2 100644 --- a/bgpd/bgp_vpn.h +++ b/bgpd/bgp_vpn.h @@ -25,6 +25,6 @@ extern int show_adj_route_vpn(struct vty *vty, struct peer *peer, struct prefix_rd *prd, afi_t afi, safi_t safi, - uint8_t use_json); + bool use_json); #endif /* _QUAGGA_BGP_VPN_H */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 99c6f39230..3669ea7736 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -301,7 +301,7 @@ int argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index, int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty, struct cmd_token **argv, int argc, int *idx, afi_t *afi, safi_t *safi, - struct bgp **bgp) + struct bgp **bgp, bool use_json) { char *vrf_name = NULL; @@ -325,9 +325,11 @@ int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty, else { *bgp = bgp_lookup_by_name(vrf_name); if (!*bgp) { - vty_out(vty, - "View/Vrf specified is unknown: %s\n", - vrf_name); + if (use_json) + vty_out(vty, "{}\n"); + else + vty_out(vty, "View/Vrf %s is unknown\n", + vrf_name); *idx = 0; return 0; } @@ -335,7 +337,11 @@ int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty, } else { *bgp = bgp_get_default(); if (!*bgp) { - vty_out(vty, "Unable to find default BGP instance\n"); + if (use_json) + vty_out(vty, "{}\n"); + else + vty_out(vty, + "Default BGP instance not found\n"); *idx = 0; return 0; } @@ -7343,7 +7349,7 @@ DEFUN (show_bgp_vrfs, struct list *inst = bm->bgp; struct listnode *node; struct bgp *bgp; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); json_object *json = NULL; json_object *json_vrfs = NULL; int count = 0; @@ -7672,7 +7678,7 @@ static void bgp_show_bestpath_json(struct bgp *bgp, json_object *json) /* Show BGP peer's summary information. */ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, - uint8_t use_json, json_object *json) + bool use_json, json_object *json) { struct peer *peer; struct listnode *node, *nnode; @@ -8089,14 +8095,14 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, } static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi, - int safi, uint8_t use_json, + int safi, bool use_json, json_object *json) { int is_first = 1; int afi_wildcard = (afi == AFI_MAX); int safi_wildcard = (safi == SAFI_MAX); int is_wildcard = (afi_wildcard || safi_wildcard); - bool json_output = false; + bool nbr_output = false; if (use_json && is_wildcard) vty_out(vty, "{\n"); @@ -8107,7 +8113,7 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi, safi = 1; /* SAFI_UNICAST */ while (safi < SAFI_MAX) { if (bgp_afi_safi_peer_exists(bgp, afi, safi)) { - json_output = true; + nbr_output = true; if (is_wildcard) { /* * So limit output to those afi/safi @@ -8146,22 +8152,28 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi, if (use_json && is_wildcard) vty_out(vty, "}\n"); - else if (use_json && !json_output) - vty_out(vty, "{}\n"); + else if (!nbr_output) { + if (use_json) + vty_out(vty, "{}\n"); + else + vty_out(vty, "%% No BGP neighbors found\n"); + } } static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi, - safi_t safi, uint8_t use_json) + safi_t safi, bool use_json) { struct listnode *node, *nnode; struct bgp *bgp; json_object *json = NULL; int is_first = 1; + bool nbr_output = false; if (use_json) vty_out(vty, "{\n"); for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + nbr_output = true; if (use_json) { json = json_object_new_object(); @@ -8185,10 +8197,12 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi, if (use_json) vty_out(vty, "}\n"); + else if (!nbr_output) + vty_out(vty, "%% BGP instance not found\n"); } int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, - safi_t safi, uint8_t use_json) + safi_t safi, bool use_json) { struct bgp *bgp; @@ -8205,7 +8219,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, vty_out(vty, "{}\n"); else vty_out(vty, - "%% No such BGP instance exist\n"); + "%% BGP instance not found\n"); return CMD_WARNING; } @@ -8219,6 +8233,13 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, if (bgp) bgp_show_summary_afi_safi(vty, bgp, afi, safi, use_json, NULL); + else { + if (use_json) + vty_out(vty, "{}\n"); + else + vty_out(vty, "%% BGP instance not found\n"); + return CMD_WARNING; + } return CMD_SUCCESS; } @@ -8258,7 +8279,7 @@ DEFUN (show_ip_bgp_summary, argv_find_and_parse_safi(argv, argc, &idx, &safi); } - int uj = use_json(argc, argv); + bool uj = use_json(argc, argv); return bgp_show_summary_vty(vty, vrf, afi, safi, uj); } @@ -8340,7 +8361,7 @@ static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p, afi_t afi, safi_t safi, uint16_t adv_smcap, uint16_t adv_rmcap, uint16_t rcv_smcap, uint16_t rcv_rmcap, - uint8_t use_json, json_object *json_pref) + bool use_json, json_object *json_pref) { /* Send-Mode */ if (CHECK_FLAG(p->af_cap[afi][safi], adv_smcap) @@ -8400,7 +8421,7 @@ static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p, } static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, - safi_t safi, uint8_t use_json, + safi_t safi, bool use_json, json_object *json_neigh) { struct bgp_filter *filter; @@ -8975,7 +8996,7 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, } } -static void bgp_show_peer(struct vty *vty, struct peer *p, uint8_t use_json, +static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_object *json) { struct bgp *bgp; @@ -10722,12 +10743,13 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, uint8_t use_json, static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, enum show_type type, union sockunion *su, - const char *conf_if, uint8_t use_json, + const char *conf_if, bool use_json, json_object *json) { struct listnode *node, *nnode; struct peer *peer; int find = 0; + bool nbr_output = false; for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) @@ -10736,6 +10758,7 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, switch (type) { case show_all: bgp_show_peer(vty, peer, use_json, json); + nbr_output = true; break; case show_peer: if (conf_if) { @@ -10765,6 +10788,9 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, vty_out(vty, "%% No such neighbor in this view/vrf\n"); } + if (type != show_peer && !nbr_output && !use_json) + vty_out(vty, "%% No BGP neighbors found\n"); + if (use_json) { vty_out(vty, "%s\n", json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY)); @@ -10779,18 +10805,20 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, static void bgp_show_all_instances_neighbors_vty(struct vty *vty, enum show_type type, const char *ip_str, - uint8_t use_json) + bool use_json) { struct listnode *node, *nnode; struct bgp *bgp; union sockunion su; json_object *json = NULL; int ret, is_first = 1; + bool nbr_output = false; if (use_json) vty_out(vty, "{\n"); for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + nbr_output = true; if (use_json) { if (!(json = json_object_new_object())) { flog_err( @@ -10843,11 +10871,13 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty, if (use_json) vty_out(vty, "}\n"); + else if (!nbr_output) + vty_out(vty, "%% BGP instance not found\n"); } static int bgp_show_neighbor_vty(struct vty *vty, const char *name, enum show_type type, const char *ip_str, - uint8_t use_json) + bool use_json) { int ret; struct bgp *bgp; @@ -10864,8 +10894,6 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name, if (!bgp) { if (use_json) { json = json_object_new_object(); - json_object_boolean_true_add( - json, "bgpNoSuchInstance"); vty_out(vty, "%s\n", json_object_to_json_string_ext( json, @@ -10873,7 +10901,7 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name, json_object_free(json); } else vty_out(vty, - "%% No such BGP instance exist\n"); + "%% BGP instance not found\n"); return CMD_WARNING; } @@ -10897,6 +10925,11 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name, json); } json_object_free(json); + } else { + if (use_json) + vty_out(vty, "{}\n"); + else + vty_out(vty, "%% BGP instance not found\n"); } return CMD_SUCCESS; @@ -10922,7 +10955,7 @@ DEFUN (show_ip_bgp_neighbors, char *sh_arg = NULL; enum show_type sh_type; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); int idx = 0; @@ -11037,8 +11070,8 @@ DEFUN (show_ip_bgp_attr_info, return CMD_SUCCESS; } -static int bgp_show_route_leak_vty(struct vty *vty, const char *name, - afi_t afi, safi_t safi, uint8_t use_json) +static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi, + safi_t safi, bool use_json) { struct bgp *bgp; struct listnode *node; @@ -11054,16 +11087,9 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name, json = json_object_new_object(); - /* Provide context for the block */ - json_object_string_add(json, "vrf", name ? name : "default"); - json_object_string_add(json, "afiSafi", - afi_safi_print(afi, safi)); - bgp = name ? bgp_lookup_by_name(name) : bgp_get_default(); if (!bgp) { - json_object_boolean_true_add(json, - "bgpNoSuchInstance"); vty_out(vty, "%s\n", json_object_to_json_string_ext( json, @@ -11073,6 +11099,11 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name, return CMD_WARNING; } + /* Provide context for the block */ + json_object_string_add(json, "vrf", name ? name : "default"); + json_object_string_add(json, "afiSafi", + afi_safi_print(afi, safi)); + if (!CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT)) { json_object_string_add(json, "importFromVrfs", "none"); @@ -11211,7 +11242,7 @@ DEFUN (show_ip_bgp_route_leak, afi_t afi = AFI_MAX; safi_t safi = SAFI_MAX; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); int idx = 0; /* show [ip] bgp */ @@ -11536,7 +11567,7 @@ static int bgp_show_peer_group_vty(struct vty *vty, const char *name, bgp = name ? bgp_lookup_by_name(name) : bgp_get_default(); if (!bgp) { - vty_out(vty, "%% No such BGP instance exists\n"); + vty_out(vty, "%% BGP instance not found\n"); return CMD_WARNING; } diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index afb85f112b..d9df2b4cfe 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -69,9 +69,10 @@ extern int argv_find_and_parse_safi(struct cmd_token **argv, int argc, extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty, struct cmd_token **argv, int argc, int *idx, afi_t *afi, - safi_t *safi, struct bgp **bgp); + safi_t *safi, struct bgp **bgp, + bool use_json); extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, - safi_t safi, uint8_t use_json); + safi_t safi, bool use_json); extern void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, afi_t afi); #endif /* _QUAGGA_BGP_VTY_H */ diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index f42c16c1c1..43afc317e9 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -2380,7 +2380,8 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient, int ipa_len; char buf[ETHER_ADDR_STRLEN]; char buf1[INET6_ADDRSTRLEN]; - uint8_t flags; + uint8_t flags = 0; + uint32_t seqnum = 0; memset(&ip, 0, sizeof(ip)); s = zclient->ibuf; @@ -2401,20 +2402,24 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient, (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 : IPADDR_V6; stream_get(&ip.ip.addr, s, ipa_len); } - flags = stream_getc(s); + if (command == ZEBRA_MACIP_ADD) { + flags = stream_getc(s); + seqnum = stream_getl(s); + } bgp = bgp_lookup_by_vrf_id(vrf_id); if (!bgp) return 0; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u", + zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u seq %u", vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags, prefix_mac2str(&mac, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni); + ipaddr2str(&ip, buf1, sizeof(buf1)), vni, seqnum); if (command == ZEBRA_MACIP_ADD) - return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, flags); + return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, + flags, seqnum); else return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip); } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index e6c517a9f9..a9707a7fc7 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -6626,7 +6626,7 @@ int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi, } /* Display peer uptime.*/ -char *peer_uptime(time_t uptime2, char *buf, size_t len, uint8_t use_json, +char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json, json_object *json) { time_t uptime1, epoch_tbuf; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 06eb86da95..8a99741390 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1513,7 +1513,8 @@ extern struct peer *peer_create(union sockunion *, const char *, struct bgp *, struct peer_group *); extern struct peer *peer_create_accept(struct bgp *); extern void peer_xfer_config(struct peer *dst, struct peer *src); -extern char *peer_uptime(time_t, char *, size_t, uint8_t, json_object *); +extern char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json, + json_object *json); extern int bgp_config_write(struct vty *); diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index 8553846c90..f1dd08fda0 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -23,7 +23,7 @@ #include "lib/prefix.h" #include "lib/memory.h" #include "lib/linklist.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/plist.h" #include "lib/routemap.h" @@ -126,10 +126,10 @@ struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc, struct rfapi_nve_group_cfg *rfg_vn = NULL; struct rfapi_nve_group_cfg *rfg_un = NULL; - struct route_table *rt_vn; - struct route_table *rt_un; - struct route_node *rn_vn; - struct route_node *rn_un; + struct agg_table *rt_vn; + struct agg_table *rt_un; + struct agg_node *rn_vn; + struct agg_node *rn_un; struct rfapi_nve_group_cfg *rfg; struct listnode *node, *nnode; @@ -156,16 +156,16 @@ struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc, return NULL; } - rn_vn = route_node_match(rt_vn, vn); /* NB locks node */ + rn_vn = agg_node_match(rt_vn, vn); /* NB locks node */ if (rn_vn) { rfg_vn = rn_vn->info; - route_unlock_node(rn_vn); + agg_unlock_node(rn_vn); } - rn_un = route_node_match(rt_un, un); /* NB locks node */ + rn_un = agg_node_match(rt_un, un); /* NB locks node */ if (rn_un) { rfg_un = rn_un->info; - route_unlock_node(rn_un); + agg_unlock_node(rn_un); } #if BGP_VNC_DEBUG_MATCH_GROUP @@ -2304,11 +2304,11 @@ static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */ if (rfg->vn_node) { rfg->vn_node->info = NULL; - route_unlock_node(rfg->vn_node); /* frees */ + agg_unlock_node(rfg->vn_node); /* frees */ } if (rfg->un_node) { rfg->un_node->info = NULL; - route_unlock_node(rfg->un_node); /* frees */ + agg_unlock_node(rfg->un_node); /* frees */ } if (rfg->rfp_cfg) XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); @@ -2468,8 +2468,8 @@ DEFUN (vnc_nve_group_prefix, VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); struct prefix p; afi_t afi; - struct route_table *rt; - struct route_node *rn; + struct agg_table *rt; + struct agg_node *rn; int is_un_prefix = 0; /* make sure it's still in list */ @@ -2497,12 +2497,12 @@ DEFUN (vnc_nve_group_prefix, rt = bgp->rfapi_cfg->nve_groups_vn[afi]; } - rn = route_node_get(rt, &p); /* NB locks node */ + rn = agg_node_get(rt, &p); /* NB locks node */ if (rn->info) { /* * There is already a group with this prefix */ - route_unlock_node(rn); + agg_unlock_node(rn); if (rn->info != rfg) { /* * different group name: fail @@ -2535,7 +2535,7 @@ DEFUN (vnc_nve_group_prefix, /* detach rfg from previous route table location */ if (rfg->un_node) { rfg->un_node->info = NULL; - route_unlock_node(rfg->un_node); /* frees */ + agg_unlock_node(rfg->un_node); /* frees */ } rfg->un_node = rn; /* back ref */ rfg->un_prefix = p; @@ -2545,7 +2545,7 @@ DEFUN (vnc_nve_group_prefix, /* detach rfg from previous route table location */ if (rfg->vn_node) { rfg->vn_node->info = NULL; - route_unlock_node(rfg->vn_node); /* frees */ + agg_unlock_node(rfg->vn_node); /* frees */ } rfg->vn_node = rn; /* back ref */ rfg->vn_prefix = p; @@ -3761,8 +3761,8 @@ struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg) h->nve_groups_sequential = list_new(); assert(h->nve_groups_sequential); for (afi = AFI_IP; afi < AFI_MAX; afi++) { - h->nve_groups_vn[afi] = route_table_init(); - h->nve_groups_un[afi] = route_table_init(); + h->nve_groups_vn[afi] = agg_table_init(); + h->nve_groups_un[afi] = agg_table_init(); } h->default_response_lifetime = BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT; @@ -3820,8 +3820,8 @@ void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h) if (h->default_rfp_cfg) XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg); for (afi = AFI_IP; afi < AFI_MAX; afi++) { - route_table_finish(h->nve_groups_vn[afi]); - route_table_finish(h->nve_groups_un[afi]); + agg_table_finish(h->nve_groups_vn[afi]); + agg_table_finish(h->nve_groups_un[afi]); } XFREE(MTYPE_RFAPI_CFG, h); } diff --git a/bgpd/rfapi/bgp_rfapi_cfg.h b/bgpd/rfapi/bgp_rfapi_cfg.h index a11b0992fa..b72d38220b 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.h +++ b/bgpd/rfapi/bgp_rfapi_cfg.h @@ -47,8 +47,8 @@ typedef enum { } rfapi_group_cfg_type_t; struct rfapi_nve_group_cfg { - struct route_node *vn_node; /* backref */ - struct route_node *un_node; /* backref */ + struct agg_node *vn_node; /* backref */ + struct agg_node *un_node; /* backref */ rfapi_group_cfg_type_t type; /* NVE|VPN */ char *name; /* unique by type! */ @@ -135,8 +135,8 @@ struct rfapi_cfg { struct list *l2_groups; /* rfapi_l2_group_cfg list */ /* three views into the same collection of rfapi_nve_group_cfg */ struct list *nve_groups_sequential; - struct route_table *nve_groups_vn[AFI_MAX]; - struct route_table *nve_groups_un[AFI_MAX]; + struct agg_table *nve_groups_vn[AFI_MAX]; + struct agg_table *nve_groups_un[AFI_MAX]; /* * For Single VRF export to ordinary routing protocols. This is diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 355cf92053..a427608f67 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -23,7 +23,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/vty.h" #include "lib/memory.h" #include "lib/routemap.h" @@ -203,11 +203,11 @@ int rfapi_ip_addr_cmp(struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2) static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, struct rfapi_ip_addr *un_addr, - struct route_node **node) + struct agg_node **node) { struct rfapi *h; struct prefix p; - struct route_node *rn; + struct agg_node *rn; int rc; afi_t afi; @@ -228,12 +228,12 @@ static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, if ((rc = rfapiRaddr2Qprefix(un_addr, &p))) return rc; - rn = route_node_lookup(h->un[afi], &p); + rn = agg_node_lookup(h->un[afi], &p); if (!rn) return ENOENT; - route_unlock_node(rn); + agg_unlock_node(rn); *node = rn; @@ -244,7 +244,7 @@ static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, struct rfapi_ip_addr *un_addr, struct rfapi_descriptor **rfd) { - struct route_node *rn; + struct agg_node *rn; int rc; rc = rfapi_find_node(bgp, vn_addr, un_addr, &rn); @@ -1347,8 +1347,8 @@ static int rfapi_open_inner(struct rfapi_descriptor *rfd, struct bgp *bgp, #define RFD_RTINIT_AFI(rh, ary, afi) \ do { \ if (!ary[afi]) { \ - ary[afi] = route_table_init(); \ - ary[afi]->info = rh; \ + ary[afi] = agg_table_init(); \ + agg_set_table_info(ary[afi], rh); \ } \ } while (0) @@ -1394,7 +1394,7 @@ int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd, char buf_un[BUFSIZ]; afi_t afi_vn, afi_un; struct prefix pfx_un; - struct route_node *rn; + struct agg_node *rn; rfapi_time(&rfd->open_time); @@ -1423,7 +1423,7 @@ int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd, assert(afi_vn && afi_un); assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx_un)); - rn = route_node_get(h->un[afi_un], &pfx_un); + rn = agg_node_get(h->un[afi_un], &pfx_un); assert(rn); rfd->next = rn->info; rn->info = rfd; @@ -1535,7 +1535,7 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target, afi_t afi; struct prefix p; struct prefix p_original; - struct route_node *rn; + struct agg_node *rn; struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; struct bgp *bgp = rfd->bgp; struct rfapi_next_hop_entry *pNHE = NULL; @@ -1704,7 +1704,7 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target, } if (rn) { - route_lock_node(rn); /* so we can unlock below */ + agg_lock_node(rn); /* so we can unlock below */ } else { /* * returns locked node. Don't unlock yet because the @@ -1721,7 +1721,7 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target, assert(rn); if (!rn->info) { - route_unlock_node(rn); + agg_unlock_node(rn); vnc_zlog_debug_verbose( "%s: VPN route not found, returning ENOENT", __func__); return ENOENT; @@ -1758,7 +1758,7 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target, &p_original); } - route_unlock_node(rn); + agg_unlock_node(rn); done: if (ppNextHopEntry) { @@ -2170,7 +2170,7 @@ int rfapi_close(void *handle) { struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; int rc; - struct route_node *node; + struct agg_node *node; struct bgp *bgp; struct rfapi *h; @@ -2276,7 +2276,7 @@ int rfapi_close(void *handle) } } } - route_unlock_node(node); + agg_unlock_node(node); } /* @@ -2928,6 +2928,8 @@ static void test_nexthops_callback( rfapiPrintNhl(stream, next_hops); + fp(out, "\n"); + rfapi_free_next_hop_list(next_hops); } @@ -3049,7 +3051,7 @@ DEFUN (debug_rfapi_close_rfd, DEFUN (debug_rfapi_register_vn_un, debug_rfapi_register_vn_un_cmd, - "debug rfapi-dev register vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime SECONDS", + "debug rfapi-dev register vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime SECONDS [cost (0-255)]", DEBUG_STR DEBUG_RFAPI_STR "rfapi_register\n" @@ -3063,7 +3065,9 @@ DEFUN (debug_rfapi_register_vn_un, "IPv4 prefix\n" "IPv6 prefix\n" "indicate lifetime follows\n" - "lifetime\n") + "lifetime\n" + "Cost (localpref = 255-cost)\n" + "0-255\n") { struct rfapi_ip_addr vn; struct rfapi_ip_addr un; @@ -3072,6 +3076,7 @@ DEFUN (debug_rfapi_register_vn_un, uint32_t lifetime; struct rfapi_ip_prefix hpfx; int rc; + uint8_t cost = 100; /* * Get VN addr @@ -3112,8 +3117,12 @@ DEFUN (debug_rfapi_register_vn_un, lifetime = strtoul(argv[10]->arg, NULL, 10); } + if (argc >= 13) + cost = (uint8_t) strtoul(argv[12]->arg, NULL, 10); + hpfx.cost = cost; - rc = rfapi_register(handle, &hpfx, lifetime, NULL, NULL, 0); + rc = rfapi_register(handle, &hpfx, lifetime, NULL, NULL, + RFAPI_REGISTER_ADD); if (rc) { vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc, strerror(rc)); @@ -3213,7 +3222,8 @@ DEFUN (debug_rfapi_register_vn_un_l2o, /* L2 option parsing END */ /* TBD fixme */ - rc = rfapi_register(handle, &hpfx, lifetime, NULL /* &uo */, opt, 0); + rc = rfapi_register(handle, &hpfx, lifetime, NULL /* &uo */, opt, + RFAPI_REGISTER_ADD); if (rc) { vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc, strerror(rc)); @@ -3225,7 +3235,7 @@ DEFUN (debug_rfapi_register_vn_un_l2o, DEFUN (debug_rfapi_unregister_vn_un, debug_rfapi_unregister_vn_un_cmd, - "debug rfapi-dev unregister vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M>", + "debug rfapi-dev unregister vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> [kill]", DEBUG_STR DEBUG_RFAPI_STR "rfapi_register\n" @@ -3233,7 +3243,8 @@ DEFUN (debug_rfapi_unregister_vn_un, "virtual network interface address\n" "indicate xt addr follows\n" "underlay network interface address\n" - "indicate prefix follows\n" "prefix") + "prefix to remove\n" + "Remove without holddown") { struct rfapi_ip_addr vn; struct rfapi_ip_addr un; @@ -3275,7 +3286,9 @@ DEFUN (debug_rfapi_unregister_vn_un, } rfapiQprefix2Rprefix(&pfx, &hpfx); - rfapi_register(handle, &hpfx, 0, NULL, NULL, 1); + rfapi_register(handle, &hpfx, 0, NULL, NULL, + (argc == 10 ? + RFAPI_REGISTER_KILL : RFAPI_REGISTER_WITHDRAW)); return CMD_SUCCESS; } diff --git a/bgpd/rfapi/rfapi_ap.c b/bgpd/rfapi/rfapi_ap.c index 3112505d4b..691e1e4ec8 100644 --- a/bgpd/rfapi/rfapi_ap.c +++ b/bgpd/rfapi/rfapi_ap.c @@ -22,7 +22,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/vty.h" #include "lib/memory.h" #include "lib/routemap.h" diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index ac3b6da230..4c506da686 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -27,7 +27,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/vty.h" #include "lib/memory.h" #include "lib/log.h" @@ -80,7 +80,7 @@ */ struct rfapi_withdraw { struct rfapi_import_table *import_table; - struct route_node *node; + struct agg_node *node; struct bgp_info *info; safi_t safi; /* used only for bulk operations */ /* @@ -88,8 +88,8 @@ struct rfapi_withdraw { * Normally when a timer expires, lockoffset should be 0. However, if * the timer expiration function is called directly (e.g., * rfapiExpireVpnNow), the node could be locked by a preceding - * route_top() or route_next() in a loop, so we need to pass this - * value in. + * agg_route_top() or agg_route_next() in a loop, so we need to pass + * this value in. */ int lockoffset; }; @@ -140,8 +140,8 @@ void rfapiCheckRouteCount() for (it = h->imports; it; it = it->next) { for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - struct route_table *rt; - struct route_node *rn; + struct agg_table *rt; + struct agg_node *rn; int holddown_count = 0; int local_count = 0; @@ -150,7 +150,8 @@ void rfapiCheckRouteCount() rt = it->imported_vpn[afi]; - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; + rn = agg_route_next(rn)) { struct bgp_info *bi; struct bgp_info *next; @@ -211,11 +212,11 @@ void rfapiCheckRouteCount() * Validate reference count for a node in an import table * * Normally lockoffset is 0 for nodes in quiescent state. However, - * route_unlock_node will delete the node if it is called when + * agg_unlock_node will delete the node if it is called when * node->lock == 1, and we have to validate the refcount before * the node is deleted. In this case, we specify lockoffset 1. */ -void rfapiCheckRefcount(struct route_node *rn, safi_t safi, int lockoffset) +void rfapiCheckRefcount(struct agg_node *rn, safi_t safi, int lockoffset) { unsigned int count_bi = 0; unsigned int count_monitor = 0; @@ -613,8 +614,8 @@ struct rfapi_import_table *rfapiMacImportTableGet(struct bgp *bgp, uint32_t lni) it->rt_import_list = enew; for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - it->imported_vpn[afi] = route_table_init(); - it->imported_encap[afi] = route_table_init(); + it->imported_vpn[afi] = agg_table_init(); + it->imported_encap[afi] = agg_table_init(); } it->l2_logical_net_id = lni; @@ -633,10 +634,10 @@ struct rfapi_import_table *rfapiMacImportTableGet(struct bgp *bgp, uint32_t lni) * Returns pointer to the list of moved monitors */ static struct rfapi_monitor_vpn * -rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset) +rfapiMonitorMoveShorter(struct agg_node *original_vpn_node, int lockoffset) { struct bgp_info *bi; - struct route_node *par; + struct agg_node *par; struct rfapi_monitor_vpn *m; struct rfapi_monitor_vpn *mlast; struct rfapi_monitor_vpn *moved; @@ -679,7 +680,8 @@ rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset) * one route (even if it is only a withdrawn route) with a * valid UN address. Call this node "Node P." */ - for (par = original_vpn_node->parent; par; par = par->parent) { + for (par = agg_node_parent(original_vpn_node); par; + par = agg_node_parent(par)) { for (bi = par->info; bi; bi = bi->next) { struct prefix pfx; if (!rfapiGetUnAddrOfVpnBi(bi, &pfx)) { @@ -699,14 +701,14 @@ rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset) */ if (!par) { /* this isn't necessarily 0/0 */ - par = route_top(original_vpn_node->table); + par = agg_route_table_top(original_vpn_node); /* * If we got the top node but it wasn't 0/0, * ignore it */ if (par && par->p.prefixlen) { - route_unlock_node(par); /* maybe free */ + agg_unlock_node(par); /* maybe free */ par = NULL; } @@ -725,7 +727,8 @@ rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset) pfx_default.family = original_vpn_node->p.family; /* creates default node if none exists */ - par = route_node_get(original_vpn_node->table, &pfx_default); + par = agg_node_get(agg_get_table(original_vpn_node), + &pfx_default); ++parent_already_refcounted; } @@ -764,18 +767,18 @@ rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset) RFAPI_CHECK_REFCOUNT(par, SAFI_MPLS_VPN, parent_already_refcounted - movecount); while (movecount > parent_already_refcounted) { - route_lock_node(par); + agg_lock_node(par); ++parent_already_refcounted; } while (movecount < parent_already_refcounted) { /* unlikely, but code defensively */ - route_unlock_node(par); + agg_unlock_node(par); --parent_already_refcounted; } RFAPI_CHECK_REFCOUNT(original_vpn_node, SAFI_MPLS_VPN, movecount + lockoffset); while (movecount--) { - route_unlock_node(original_vpn_node); + agg_unlock_node(original_vpn_node); } #if DEBUG_MONITOR_MOVE_SHORTER @@ -796,12 +799,12 @@ rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset) * Implement MONITOR_MOVE_LONGER(new_node) from * RFAPI-Import-Event-Handling.txt */ -static void rfapiMonitorMoveLonger(struct route_node *new_vpn_node) +static void rfapiMonitorMoveLonger(struct agg_node *new_vpn_node) { struct rfapi_monitor_vpn *monitor; struct rfapi_monitor_vpn *mlast; struct bgp_info *bi; - struct route_node *par; + struct agg_node *par; RFAPI_CHECK_REFCOUNT(new_vpn_node, SAFI_MPLS_VPN, 0); @@ -824,7 +827,8 @@ static void rfapiMonitorMoveLonger(struct route_node *new_vpn_node) /* * Find first parent node that has monitors */ - for (par = new_vpn_node->parent; par; par = par->parent) { + for (par = agg_node_parent(new_vpn_node); par; + par = agg_node_parent(par)) { if (RFAPI_MONITOR_VPN(par)) break; } @@ -860,14 +864,14 @@ static void rfapiMonitorMoveLonger(struct route_node *new_vpn_node) RFAPI_MONITOR_VPN_W_ALLOC(new_vpn_node) = monitor; monitor->node = new_vpn_node; - route_lock_node(new_vpn_node); /* incr refcount */ + agg_lock_node(new_vpn_node); /* incr refcount */ monitor = mlast ? mlast->next : RFAPI_MONITOR_VPN(par); RFAPI_CHECK_REFCOUNT(par, SAFI_MPLS_VPN, 1); /* decr refcount after we're done with par as this might * free it */ - route_unlock_node(par); + agg_unlock_node(par); continue; } @@ -919,10 +923,10 @@ static void rfapiImportTableFlush(struct rfapi_import_table *it) for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - struct route_node *rn; + struct agg_node *rn; - for (rn = route_top(it->imported_vpn[afi]); rn; - rn = route_next(rn)) { + for (rn = agg_route_top(it->imported_vpn[afi]); rn; + rn = agg_route_next(rn)) { /* * Each route_node has: * aggregate: points to rfapi_it_extra with monitor @@ -936,8 +940,8 @@ static void rfapiImportTableFlush(struct rfapi_import_table *it) rfapiMonitorExtraFlush(SAFI_MPLS_VPN, rn); } - for (rn = route_top(it->imported_encap[afi]); rn; - rn = route_next(rn)) { + for (rn = agg_route_top(it->imported_encap[afi]); rn; + rn = agg_route_next(rn)) { /* free bgp_info and its children */ rfapiBgpInfoChainFree(rn->info); rn->info = NULL; @@ -945,8 +949,8 @@ static void rfapiImportTableFlush(struct rfapi_import_table *it) rfapiMonitorExtraFlush(SAFI_ENCAP, rn); } - route_table_finish(it->imported_vpn[afi]); - route_table_finish(it->imported_encap[afi]); + agg_table_finish(it->imported_vpn[afi]); + agg_table_finish(it->imported_encap[afi]); } if (it->monitor_exterior_orphans) { skiplist_free(it->monitor_exterior_orphans); @@ -1293,9 +1297,9 @@ int rfapi_extract_l2o( static struct rfapi_next_hop_entry * rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, - struct bgp_info *bi, /* route to encode */ - uint32_t lifetime, /* use this in nhe */ - struct route_node *rn) /* req for L2 eth addr */ + struct bgp_info *bi, /* route to encode */ + uint32_t lifetime, /* use this in nhe */ + struct agg_node *rn) /* req for L2 eth addr */ { struct rfapi_next_hop_entry *new; int have_vnc_tunnel_un = 0; @@ -1481,7 +1485,7 @@ rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, return new; } -int rfapiHasNonRemovedRoutes(struct route_node *rn) +int rfapiHasNonRemovedRoutes(struct agg_node *rn) { struct bgp_info *bi; @@ -1501,7 +1505,7 @@ int rfapiHasNonRemovedRoutes(struct route_node *rn) /* * DEBUG FUNCTION */ -void rfapiDumpNode(struct route_node *rn) +void rfapiDumpNode(struct agg_node *rn) { struct bgp_info *bi; @@ -1527,14 +1531,14 @@ void rfapiDumpNode(struct route_node *rn) #endif static int rfapiNhlAddNodeRoutes( - struct route_node *rn, /* in */ + struct agg_node *rn, /* in */ struct rfapi_ip_prefix *rprefix, /* in */ uint32_t lifetime, /* in */ int removed, /* in */ struct rfapi_next_hop_entry **head, /* in/out */ struct rfapi_next_hop_entry **tail, /* in/out */ struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_node *rfd_rib_node, /* preload this NVE rib node */ + struct agg_node *rfd_rib_node, /* preload this NVE rib node */ struct prefix *pfx_target_original) /* query target */ { struct bgp_info *bi; @@ -1544,15 +1548,17 @@ static int rfapiNhlAddNodeRoutes( int count = 0; int is_l2 = (rn->p.family == AF_ETHERNET); - if (rfd_rib_node && rfd_rib_node->table && rfd_rib_node->table->info) { + if (rfd_rib_node) { + struct agg_table *atable = agg_get_table(rfd_rib_node); struct rfapi_descriptor *rfd; - rfd = (struct rfapi_descriptor *)(rfd_rib_node->table->info); + if (atable) { + rfd = agg_get_table_info(atable); - if (rfapiRibFTDFilterRecentPrefix( - rfd, rn, pfx_target_original)) - - return 0; + if (rfapiRibFTDFilterRecentPrefix(rfd, rn, + pfx_target_original)) + return 0; + } } seen_nexthops = @@ -1657,13 +1663,13 @@ static int rfapiNhlAddNodeRoutes( * matches (of course, we still travel down its child subtrees). */ static int rfapiNhlAddSubtree( - struct route_node *rn, /* in */ + struct agg_node *rn, /* in */ uint32_t lifetime, /* in */ struct rfapi_next_hop_entry **head, /* in/out */ struct rfapi_next_hop_entry **tail, /* in/out */ - struct route_node *omit_node, /* in */ + struct agg_node *omit_node, /* in */ struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload here */ + struct agg_table *rfd_rib_table, /* preload here */ struct prefix *pfx_target_original) /* query target */ { struct rfapi_ip_prefix rprefix; @@ -1671,65 +1677,67 @@ static int rfapiNhlAddSubtree( /* FIXME: need to find a better way here to work without sticking our * hands in node->link */ - if (rn->l_left && rn->l_left != omit_node) { - if (rn->l_left->info) { + if (agg_node_left(rn) && agg_node_left(rn) != omit_node) { + if (agg_node_left(rn)->info) { int count = 0; - struct route_node *rib_rn = NULL; + struct agg_node *rib_rn = NULL; - rfapiQprefix2Rprefix(&rn->l_left->p, &rprefix); + rfapiQprefix2Rprefix(&agg_node_left(rn)->p, &rprefix); if (rfd_rib_table) { - rib_rn = route_node_get(rfd_rib_table, - &rn->l_left->p); + rib_rn = agg_node_get(rfd_rib_table, + &agg_node_left(rn)->p); } count = rfapiNhlAddNodeRoutes( - rn->l_left, &rprefix, lifetime, 0, head, tail, - exclude_vnaddr, rib_rn, pfx_target_original); + agg_node_left(rn), &rprefix, lifetime, 0, head, + tail, exclude_vnaddr, rib_rn, + pfx_target_original); if (!count) { count = rfapiNhlAddNodeRoutes( - rn->l_left, &rprefix, lifetime, 1, head, - tail, exclude_vnaddr, rib_rn, + agg_node_left(rn), &rprefix, lifetime, + 1, head, tail, exclude_vnaddr, rib_rn, pfx_target_original); } rcount += count; if (rib_rn) - route_unlock_node(rib_rn); + agg_unlock_node(rib_rn); } } - if (rn->l_right && rn->l_right != omit_node) { - if (rn->l_right->info) { + if (agg_node_right(rn) && agg_node_right(rn) != omit_node) { + if (agg_node_right(rn)->info) { int count = 0; - struct route_node *rib_rn = NULL; + struct agg_node *rib_rn = NULL; - rfapiQprefix2Rprefix(&rn->l_right->p, &rprefix); + rfapiQprefix2Rprefix(&agg_node_right(rn)->p, &rprefix); if (rfd_rib_table) { - rib_rn = route_node_get(rfd_rib_table, - &rn->l_right->p); + rib_rn = agg_node_get(rfd_rib_table, + &agg_node_right(rn)->p); } count = rfapiNhlAddNodeRoutes( - rn->l_right, &rprefix, lifetime, 0, head, tail, - exclude_vnaddr, rib_rn, pfx_target_original); + agg_node_right(rn), &rprefix, lifetime, 0, head, + tail, exclude_vnaddr, rib_rn, + pfx_target_original); if (!count) { count = rfapiNhlAddNodeRoutes( - rn->l_right, &rprefix, lifetime, 1, - head, tail, exclude_vnaddr, rib_rn, + agg_node_right(rn), &rprefix, lifetime, + 1, head, tail, exclude_vnaddr, rib_rn, pfx_target_original); } rcount += count; if (rib_rn) - route_unlock_node(rib_rn); + agg_unlock_node(rib_rn); } } - if (rn->l_left) { + if (agg_node_left(rn)) { rcount += rfapiNhlAddSubtree( - rn->l_left, lifetime, head, tail, omit_node, + agg_node_left(rn), lifetime, head, tail, omit_node, exclude_vnaddr, rfd_rib_table, pfx_target_original); } - if (rn->l_right) { + if (agg_node_right(rn)) { rcount += rfapiNhlAddSubtree( - rn->l_right, lifetime, head, tail, omit_node, + agg_node_right(rn), lifetime, head, tail, omit_node, exclude_vnaddr, rfd_rib_table, pfx_target_original); } @@ -1748,17 +1756,17 @@ static int rfapiNhlAddSubtree( * next less-specific node (i.e., this node's parent) at the end. */ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( - struct route_node *rn, uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload here */ - struct prefix *pfx_target_original) /* query target */ + struct agg_node *rn, uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct agg_table *rfd_rib_table, /* preload here */ + struct prefix *pfx_target_original) /* query target */ { struct rfapi_ip_prefix rprefix; struct rfapi_next_hop_entry *answer = NULL; struct rfapi_next_hop_entry *last = NULL; - struct route_node *parent; + struct agg_node *parent; int count = 0; - struct route_node *rib_rn; + struct agg_node *rib_rn; #if DEBUG_RETURNED_NHL { @@ -1773,7 +1781,7 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( rfapiQprefix2Rprefix(&rn->p, &rprefix); - rib_rn = rfd_rib_table ? route_node_get(rfd_rib_table, &rn->p) : NULL; + rib_rn = rfd_rib_table ? agg_node_get(rfd_rib_table, &rn->p) : NULL; /* * Add non-withdrawn routes at this node @@ -1795,7 +1803,7 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( rfapiPrintNhl(NULL, answer); #endif if (rib_rn) - route_unlock_node(rib_rn); + agg_unlock_node(rib_rn); return answer; } @@ -1806,7 +1814,7 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( exclude_vnaddr, rib_rn, pfx_target_original); if (rib_rn) - route_unlock_node(rib_rn); + agg_unlock_node(rib_rn); // rfapiPrintNhl(NULL, answer); @@ -1814,7 +1822,8 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( * walk up the tree until we find a node with non-deleted * routes, then add them */ - for (parent = rn->parent; parent; parent = parent->parent) { + for (parent = agg_node_parent(rn); parent; + parent = agg_node_parent(parent)) { if (rfapiHasNonRemovedRoutes(parent)) { break; } @@ -1824,9 +1833,8 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( * Add non-withdrawn routes from less-specific prefix */ if (parent) { - rib_rn = rfd_rib_table - ? route_node_get(rfd_rib_table, &parent->p) - : NULL; + rib_rn = rfd_rib_table ? agg_node_get(rfd_rib_table, &parent->p) + : NULL; rfapiQprefix2Rprefix(&parent->p, &rprefix); count += rfapiNhlAddNodeRoutes(parent, &rprefix, lifetime, 0, &answer, &last, exclude_vnaddr, @@ -1835,7 +1843,7 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( rn, exclude_vnaddr, rfd_rib_table, pfx_target_original); if (rib_rn) - route_unlock_node(rib_rn); + agg_unlock_node(rib_rn); } else { /* * There is no parent with non-removed routes. Still need to @@ -1861,19 +1869,18 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( * Construct nexthop list of all routes in table */ struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList( - struct route_table *rt, - uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload this NVE rib table */ - struct prefix *pfx_target_original) /* query target */ + struct agg_table *rt, uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct agg_table *rfd_rib_table, /* preload this NVE rib table */ + struct prefix *pfx_target_original) /* query target */ { - struct route_node *rn; + struct agg_node *rn; struct rfapi_next_hop_entry *biglist = NULL; struct rfapi_next_hop_entry *nhl; struct rfapi_next_hop_entry *tail = NULL; int count = 0; - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) { nhl = rfapiRouteNode2NextHopList(rn, lifetime, exclude_vnaddr, rfd_rib_table, @@ -1898,18 +1905,18 @@ struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList( } struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList( - struct route_node *rn, struct rfapi_ip_prefix *rprefix, + struct agg_node *rn, struct rfapi_ip_prefix *rprefix, uint32_t lifetime, /* put into nexthop entries */ struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload NVE rib table */ + struct agg_table *rfd_rib_table, /* preload NVE rib table */ struct prefix *pfx_target_original) /* query target */ { int count = 0; struct rfapi_next_hop_entry *answer = NULL; struct rfapi_next_hop_entry *last = NULL; - struct route_node *rib_rn; + struct agg_node *rib_rn; - rib_rn = rfd_rib_table ? route_node_get(rfd_rib_table, &rn->p) : NULL; + rib_rn = rfd_rib_table ? agg_node_get(rfd_rib_table, &rn->p) : NULL; count = rfapiNhlAddNodeRoutes(rn, rprefix, lifetime, 0, &answer, &last, NULL, rib_rn, pfx_target_original); @@ -1928,7 +1935,7 @@ struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList( } if (rib_rn) - route_unlock_node(rib_rn); + agg_unlock_node(rib_rn); #if DEBUG_RETURNED_NHL rfapiPrintNhl(NULL, answer); @@ -1945,13 +1952,13 @@ struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList( uint32_t logical_net_id, struct rfapi_ip_prefix *rprefix, uint32_t lifetime, /* put into nexthop entries */ struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload NVE rib node */ + struct agg_table *rfd_rib_table, /* preload NVE rib node */ struct prefix *pfx_target_original) /* query target */ { struct rfapi_import_table *it; struct bgp *bgp = bgp_get_default(); - struct route_table *rt; - struct route_node *rn; + struct agg_table *rt; + struct agg_node *rn; struct rfapi_next_hop_entry *biglist = NULL; struct rfapi_next_hop_entry *nhl; struct rfapi_next_hop_entry *tail = NULL; @@ -1961,7 +1968,7 @@ struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList( it = rfapiMacImportTableGet(bgp, logical_net_id); rt = it->imported_vpn[AFI_L2VPN]; - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) { nhl = rfapiEthRouteNode2NextHopList( rn, rprefix, lifetime, exclude_vnaddr, rfd_rib_table, @@ -1989,7 +1996,7 @@ struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList( * Insert a new bi to the imported route table node, * keeping the list of BIs sorted best route first */ -static void rfapiBgpInfoAttachSorted(struct route_node *rn, +static void rfapiBgpInfoAttachSorted(struct agg_node *rn, struct bgp_info *info_new, afi_t afi, safi_t safi) { @@ -2031,7 +2038,7 @@ static void rfapiBgpInfoAttachSorted(struct route_node *rn, bgp_attr_intern(info_new->attr); } -static void rfapiBgpInfoDetach(struct route_node *rn, struct bgp_info *bi) +static void rfapiBgpInfoDetach(struct agg_node *rn, struct bgp_info *bi) { /* * Remove the route (doubly-linked) @@ -2127,8 +2134,8 @@ static int rfapi_bi_peer_rd_aux_cmp(void *b1, void *b2) /* * Index on RD and Peer */ -static void rfapiItBiIndexAdd(struct route_node *rn, /* Import table VPN node */ - struct bgp_info *bi) /* new BI */ +static void rfapiItBiIndexAdd(struct agg_node *rn, /* Import table VPN node */ + struct bgp_info *bi) /* new BI */ { struct skiplist *sl; @@ -2153,15 +2160,15 @@ static void rfapiItBiIndexAdd(struct route_node *rn, /* Import table VPN node */ sl = skiplist_new(0, rfapi_bi_peer_rd_cmp, NULL); } RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd = sl; - route_lock_node(rn); /* for skiplist */ + agg_lock_node(rn); /* for skiplist */ } assert(!skiplist_insert(sl, (void *)bi, (void *)bi)); - route_lock_node(rn); /* for skiplist entry */ + agg_lock_node(rn); /* for skiplist entry */ /* NB: BIs in import tables are not refcounted */ } -static void rfapiItBiIndexDump(struct route_node *rn) +static void rfapiItBiIndexDump(struct agg_node *rn) { struct skiplist *sl; void *cursor = NULL; @@ -2192,7 +2199,7 @@ static void rfapiItBiIndexDump(struct route_node *rn) } static struct bgp_info *rfapiItBiIndexSearch( - struct route_node *rn, /* Import table VPN node */ + struct agg_node *rn, /* Import table VPN node */ struct prefix_rd *prd, struct peer *peer, struct prefix *aux_prefix) /* optional L3 addr for L2 ITs */ { @@ -2298,8 +2305,8 @@ static struct bgp_info *rfapiItBiIndexSearch( return bi_result; } -static void rfapiItBiIndexDel(struct route_node *rn, /* Import table VPN node */ - struct bgp_info *bi) /* old BI */ +static void rfapiItBiIndexDel(struct agg_node *rn, /* Import table VPN node */ + struct bgp_info *bi) /* old BI */ { struct skiplist *sl; int rc; @@ -2322,7 +2329,7 @@ static void rfapiItBiIndexDel(struct route_node *rn, /* Import table VPN node */ } assert(!rc); - route_unlock_node(rn); /* for skiplist entry */ + agg_unlock_node(rn); /* for skiplist entry */ /* NB: BIs in import tables are not refcounted */ } @@ -2332,17 +2339,16 @@ static void rfapiItBiIndexDel(struct route_node *rn, /* Import table VPN node */ * refers to it */ static void rfapiMonitorEncapAdd(struct rfapi_import_table *import_table, - struct prefix *p, /* VN address */ - struct route_node *vpn_rn, /* VPN node */ - struct bgp_info *vpn_bi) /* VPN bi/route */ + struct prefix *p, /* VN address */ + struct agg_node *vpn_rn, /* VPN node */ + struct bgp_info *vpn_bi) /* VPN bi/route */ { afi_t afi = family2afi(p->family); - struct route_node *rn; + struct agg_node *rn; struct rfapi_monitor_encap *m; assert(afi); - rn = route_node_get(import_table->imported_encap[afi], - p); /* locks rn */ + rn = agg_node_get(import_table->imported_encap[afi], p); /* locks rn */ assert(rn); m = XCALLOC(MTYPE_RFAPI_MONITOR_ENCAP, @@ -2399,7 +2405,7 @@ static void rfapiMonitorEncapDelete(struct bgp_info *vpn_bi) * freed */ rfapiMonitorExtraPrune(SAFI_ENCAP, hme->rn); - route_unlock_node(hme->rn); /* decr ref count */ + agg_unlock_node(hme->rn); /* decr ref count */ XFREE(MTYPE_RFAPI_MONITOR_ENCAP, hme); vpn_bi->extra->vnc.import.hme = NULL; } @@ -2533,7 +2539,7 @@ done: } RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_MPLS_VPN, 1 + wcb->lockoffset); - route_unlock_node(wcb->node); /* decr ref count */ + agg_unlock_node(wcb->node); /* decr ref count */ XFREE(MTYPE_RFAPI_WITHDRAW, wcb); return 0; } @@ -2660,7 +2666,7 @@ static void rfapiCopyUnEncap2VPN(struct bgp_info *encap_bi, */ static int rfapiWithdrawEncapUpdateCachedUn( struct rfapi_import_table *import_table, struct bgp_info *encap_bi, - struct route_node *vpn_rn, struct bgp_info *vpn_bi) + struct agg_node *vpn_rn, struct bgp_info *vpn_bi) { if (!encap_bi) { @@ -2762,7 +2768,7 @@ static int rfapiWithdrawTimerEncap(struct thread *t) /* * for each VPN node referenced in the ENCAP monitors: */ - struct route_node *rn; + struct agg_node *rn; while (!skiplist_first(vpn_node_sl, (void **)&rn, NULL)) { if (!wcb->node->info) { struct rfapi_monitor_vpn *moved; @@ -2783,7 +2789,7 @@ static int rfapiWithdrawTimerEncap(struct thread *t) done: RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_ENCAP, 1); - route_unlock_node(wcb->node); /* decr ref count */ + agg_unlock_node(wcb->node); /* decr ref count */ XFREE(MTYPE_RFAPI_WITHDRAW, wcb); skiplist_free(vpn_node_sl); return 0; @@ -2796,7 +2802,7 @@ done: */ static void rfapiBiStartWithdrawTimer(struct rfapi_import_table *import_table, - struct route_node *rn, struct bgp_info *bi, afi_t afi, + struct agg_node *rn, struct bgp_info *bi, afi_t afi, safi_t safi, int (*timer_service_func)(struct thread *)) { @@ -2886,7 +2892,7 @@ typedef void(rfapi_bi_filtered_import_f)(struct rfapi_import_table *, int, static void rfapiExpireEncapNow(struct rfapi_import_table *it, - struct route_node *rn, struct bgp_info *bi) + struct agg_node *rn, struct bgp_info *bi) { struct rfapi_withdraw *wcb; struct thread t; @@ -2939,8 +2945,8 @@ static void rfapiBgpInfoFilteredImportEncap( uint8_t sub_type, /* part of bgp_info */ uint32_t *label) /* part of bgp_info */ { - struct route_table *rt = NULL; - struct route_node *rn; + struct agg_table *rt = NULL; + struct agg_node *rn; struct bgp_info *info_new; struct bgp_info *bi; struct bgp_info *next; @@ -3034,10 +3040,10 @@ static void rfapiBgpInfoFilteredImportEncap( } /* - * route_node_lookup returns a node only if there is at least + * agg_node_lookup returns a node only if there is at least * one route attached. */ - rn = route_node_lookup(rt, p); + rn = agg_node_lookup(rt, p); #if DEBUG_ENCAP_MONITOR vnc_zlog_debug_verbose("%s: initial encap lookup(it=%p) rn=%p", @@ -3047,7 +3053,7 @@ static void rfapiBgpInfoFilteredImportEncap( if (rn) { RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, 1); - route_unlock_node(rn); /* undo lock in route_node_lookup */ + agg_unlock_node(rn); /* undo lock in agg_node_lookup */ /* @@ -3187,9 +3193,9 @@ static void rfapiBgpInfoFilteredImportEncap( if (rn) { if (!replacing) - route_lock_node(rn); /* incr ref count for new BI */ + agg_lock_node(rn); /* incr ref count for new BI */ } else { - rn = route_node_get(rt, p); + rn = agg_node_get(rt, p); } vnc_zlog_debug_verbose( @@ -3254,7 +3260,7 @@ static void rfapiBgpInfoFilteredImportEncap( struct rfapi_monitor_encap *m; struct rfapi_monitor_encap *mnext; - struct route_node *referenced_vpn_prefix; + struct agg_node *referenced_vpn_prefix; /* * Optimized approach: build radix tree on the fly to @@ -3265,9 +3271,9 @@ static void rfapiBgpInfoFilteredImportEncap( * struct rfapi_monitor_encap, each of which refers to a * specific VPN node. */ - struct route_table *referenced_vpn_table; + struct agg_table *referenced_vpn_table; - referenced_vpn_table = route_table_init(); + referenced_vpn_table = agg_table_init(); assert(referenced_vpn_table); /* @@ -3306,8 +3312,8 @@ static void rfapiBgpInfoFilteredImportEncap( * per prefix. */ - referenced_vpn_prefix = route_node_get( - referenced_vpn_table, &m->node->p); + referenced_vpn_prefix = + agg_node_get(referenced_vpn_table, &m->node->p); assert(referenced_vpn_prefix); for (mnext = referenced_vpn_prefix->info; mnext; mnext = mnext->next) { @@ -3320,7 +3326,7 @@ static void rfapiBgpInfoFilteredImportEncap( /* * already have an entry for this VPN node */ - route_unlock_node(referenced_vpn_prefix); + agg_unlock_node(referenced_vpn_prefix); } else { mnext = XCALLOC( MTYPE_RFAPI_MONITOR_ENCAP, @@ -3335,16 +3341,18 @@ static void rfapiBgpInfoFilteredImportEncap( /* * for each VPN node referenced in the ENCAP monitors: */ - for (referenced_vpn_prefix = route_top(referenced_vpn_table); - referenced_vpn_prefix; referenced_vpn_prefix = route_next( - referenced_vpn_prefix)) { + for (referenced_vpn_prefix = + agg_route_top(referenced_vpn_table); + referenced_vpn_prefix; + referenced_vpn_prefix = + agg_route_next(referenced_vpn_prefix)) { while ((m = referenced_vpn_prefix->info)) { - struct route_node *n; + struct agg_node *n; rfapiMonitorMoveLonger(m->node); - for (n = m->node; n; n = n->parent) { + for (n = m->node; n; n = agg_node_parent(n)) { // rfapiDoRouteCallback(import_table, n, // NULL); } @@ -3352,18 +3360,18 @@ static void rfapiBgpInfoFilteredImportEncap( NULL); referenced_vpn_prefix->info = m->next; - route_unlock_node(referenced_vpn_prefix); + agg_unlock_node(referenced_vpn_prefix); XFREE(MTYPE_RFAPI_MONITOR_ENCAP, m); } } - route_table_finish(referenced_vpn_table); + agg_table_finish(referenced_vpn_table); } RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, 0); } static void rfapiExpireVpnNow(struct rfapi_import_table *it, - struct route_node *rn, struct bgp_info *bi, + struct agg_node *rn, struct bgp_info *bi, int lockoffset) { struct rfapi_withdraw *wcb; @@ -3398,9 +3406,9 @@ void rfapiBgpInfoFilteredImportVPN( uint8_t sub_type, /* part of bgp_info */ uint32_t *label) /* part of bgp_info */ { - struct route_table *rt = NULL; - struct route_node *rn; - struct route_node *n; + struct agg_table *rt = NULL; + struct agg_node *rn; + struct agg_node *n; struct bgp_info *info_new; struct bgp_info *bi; struct bgp_info *next; @@ -3408,7 +3416,7 @@ void rfapiBgpInfoFilteredImportVPN( struct prefix vn_prefix; struct prefix un_prefix; int un_prefix_valid = 0; - struct route_node *ern; + struct agg_node *ern; int replacing = 0; int original_had_routes = 0; struct prefix original_nexthop; @@ -3494,17 +3502,17 @@ void rfapiBgpInfoFilteredImportVPN( memset(&original_nexthop, 0, sizeof(original_nexthop)); /* - * route_node_lookup returns a node only if there is at least + * agg_node_lookup returns a node only if there is at least * one route attached. */ - rn = route_node_lookup(rt, p); + rn = agg_node_lookup(rt, p); vnc_zlog_debug_verbose("%s: rn=%p", __func__, rn); if (rn) { RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, 1); - route_unlock_node(rn); /* undo lock in route_node_lookup */ + agg_unlock_node(rn); /* undo lock in agg_node_lookup */ if (rn->info) original_had_routes = 1; @@ -3667,10 +3675,10 @@ void rfapiBgpInfoFilteredImportVPN( /* * lookup un address in encap table */ - ern = route_node_match(import_table->imported_encap[afi], &vn_prefix); + ern = agg_node_match(import_table->imported_encap[afi], &vn_prefix); if (ern) { rfapiCopyUnEncap2VPN(ern->info, info_new); - route_unlock_node(ern); /* undo lock in route_note_match */ + agg_unlock_node(ern); /* undo lock in route_note_match */ } else { char buf[PREFIX_STRLEN]; @@ -3683,13 +3691,13 @@ void rfapiBgpInfoFilteredImportVPN( if (rn) { if (!replacing) - route_lock_node(rn); + agg_lock_node(rn); } else { /* * No need to increment reference count, so only "get" * if the node is not there already */ - rn = route_node_get(rt, p); + rn = agg_node_get(rt, p); } /* @@ -3856,7 +3864,7 @@ void rfapiBgpInfoFilteredImportVPN( } if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { - for (n = rn; n; n = n->parent) { + for (n = rn; n; n = agg_node_parent(n)) { // rfapiDoRouteCallback(import_table, n, NULL); } rfapiMonitorItNodeChanged(import_table, rn, NULL); @@ -4108,9 +4116,9 @@ static void rfapiProcessPeerDownRt(struct peer *peer, struct rfapi_import_table *import_table, afi_t afi, safi_t safi) { - struct route_node *rn; + struct agg_node *rn; struct bgp_info *bi; - struct route_table *rt; + struct agg_table *rt; int (*timer_service_func)(struct thread *); assert(afi == AFI_IP || afi == AFI_IP6); @@ -4131,7 +4139,7 @@ static void rfapiProcessPeerDownRt(struct peer *peer, } - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) { for (bi = rn->info; bi; bi = bi->next) { if (bi->peer == peer) { @@ -4274,7 +4282,7 @@ struct rfapi *bgp_rfapi_new(struct bgp *bgp) h = (struct rfapi *)XCALLOC(MTYPE_RFAPI, sizeof(struct rfapi)); for (afi = AFI_IP; afi < AFI_MAX; afi++) { - h->un[afi] = route_table_init(); + h->un[afi] = agg_table_init(); } /* @@ -4282,10 +4290,10 @@ struct rfapi *bgp_rfapi_new(struct bgp *bgp) */ h->it_ce = XCALLOC(MTYPE_RFAPI_IMPORTTABLE, sizeof(struct rfapi_import_table)); - h->it_ce->imported_vpn[AFI_IP] = route_table_init(); - h->it_ce->imported_vpn[AFI_IP6] = route_table_init(); - h->it_ce->imported_encap[AFI_IP] = route_table_init(); - h->it_ce->imported_encap[AFI_IP6] = route_table_init(); + h->it_ce->imported_vpn[AFI_IP] = agg_table_init(); + h->it_ce->imported_vpn[AFI_IP6] = agg_table_init(); + h->it_ce->imported_encap[AFI_IP] = agg_table_init(); + h->it_ce->imported_encap[AFI_IP6] = agg_table_init(); rfapiBgpTableFilteredImport(bgp, h->it_ce, AFI_IP, SAFI_MPLS_VPN); rfapiBgpTableFilteredImport(bgp, h->it_ce, AFI_IP6, SAFI_MPLS_VPN); @@ -4317,10 +4325,10 @@ void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h) h->resolve_nve_nexthop = NULL; } - route_table_finish(h->it_ce->imported_vpn[AFI_IP]); - route_table_finish(h->it_ce->imported_vpn[AFI_IP6]); - route_table_finish(h->it_ce->imported_encap[AFI_IP]); - route_table_finish(h->it_ce->imported_encap[AFI_IP6]); + agg_table_finish(h->it_ce->imported_vpn[AFI_IP]); + agg_table_finish(h->it_ce->imported_vpn[AFI_IP6]); + agg_table_finish(h->it_ce->imported_encap[AFI_IP]); + agg_table_finish(h->it_ce->imported_encap[AFI_IP6]); if (h->import_mac) { struct rfapi_import_table *it; @@ -4346,7 +4354,7 @@ void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h) rfp_stop(h->rfp); for (afi = AFI_IP; afi < AFI_MAX; afi++) { - route_table_finish(h->un[afi]); + agg_table_finish(h->un[afi]); } XFREE(MTYPE_RFAPI_IMPORTTABLE, h->it_ce); @@ -4394,8 +4402,8 @@ rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list, */ for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - it->imported_vpn[afi] = route_table_init(); - it->imported_encap[afi] = route_table_init(); + it->imported_vpn[afi] = agg_table_init(); + it->imported_encap[afi] = agg_table_init(); rfapiBgpTableFilteredImport(bgp, it, afi, SAFI_MPLS_VPN); @@ -4452,8 +4460,8 @@ static void rfapiDeleteRemotePrefixesIt( for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - struct route_table *rt; - struct route_node *rn; + struct agg_table *rt; + struct agg_node *rn; if (p && (family2afi(p->family) != afi)) { continue; @@ -4466,7 +4474,7 @@ static void rfapiDeleteRemotePrefixesIt( vnc_zlog_debug_verbose("%s: scanning rt for afi=%d", __func__, afi); - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) { struct bgp_info *bi; struct bgp_info *next; diff --git a/bgpd/rfapi/rfapi_import.h b/bgpd/rfapi/rfapi_import.h index 84b7ca3a76..ae3d248367 100644 --- a/bgpd/rfapi/rfapi_import.h +++ b/bgpd/rfapi/rfapi_import.h @@ -40,10 +40,10 @@ struct rfapi_import_table { struct ecommunity *rt_import_list; /* copied from nve grp */ int refcount; /* nve grps and nves */ uint32_t l2_logical_net_id; /* L2 only: EVPN Eth Seg Id */ - struct route_table *imported_vpn[AFI_MAX]; + struct agg_table *imported_vpn[AFI_MAX]; struct rfapi_monitor_vpn *vpn0_queries[AFI_MAX]; struct rfapi_monitor_eth *eth0_queries; - struct route_table *imported_encap[AFI_MAX]; + struct agg_table *imported_encap[AFI_MAX]; struct skiplist *monitor_exterior_orphans; int local_count[AFI_MAX]; int remote_count[AFI_MAX]; @@ -80,7 +80,7 @@ extern void rfapiCheckRouteCount(void); extern void rfapiPrintBi(void *stream, struct bgp_info *bi); extern void rfapiShowImportTable(void *stream, const char *label, - struct route_table *rt, int isvpn); + struct agg_table *rt, int isvpn); extern struct rfapi_import_table * rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list, @@ -100,32 +100,31 @@ extern void rfapiImportTableRefDelByIt(struct bgp *bgp, * next less-specific node (i.e., this node's parent) at the end. */ extern struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( - struct route_node *rn, uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload this NVE rib table */ - struct prefix *pfx_target_original); /* query target */ + struct agg_node *rn, uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct agg_table *rfd_rib_table, /* preload this NVE rib table */ + struct prefix *pfx_target_original); /* query target */ extern struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList( - struct route_table *rt, - uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload this NVE rib table */ - struct prefix *pfx_target_original); /* query target */ + struct agg_table *rt, uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct agg_table *rfd_rib_table, /* preload this NVE rib table */ + struct prefix *pfx_target_original); /* query target */ extern struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList( uint32_t logical_net_id, struct rfapi_ip_prefix *rprefix, uint32_t lifetime, /* put into nexthop entries */ struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rib_route_table, /* preload NVE rib node */ + struct agg_table *rib_route_table, /* preload NVE rib node */ struct prefix *pfx_target_original); /* query target */ extern int rfapiEcommunitiesIntersect(struct ecommunity *e1, struct ecommunity *e2); -extern void rfapiCheckRefcount(struct route_node *rn, safi_t safi, +extern void rfapiCheckRefcount(struct agg_node *rn, safi_t safi, int lockoffset); -extern int rfapiHasNonRemovedRoutes(struct route_node *rn); +extern int rfapiHasNonRemovedRoutes(struct agg_node *rn); extern int rfapiProcessDeferredClose(struct thread *t); @@ -153,10 +152,10 @@ extern void rfapiBgpInfoFilteredImportVPN( uint32_t *label); /* part of bgp_info */ extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList( - struct route_node *rn, struct rfapi_ip_prefix *rprefix, + struct agg_node *rn, struct rfapi_ip_prefix *rprefix, uint32_t lifetime, /* put into nexthop entries */ struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rib_route_table, /* preload NVE rib table */ + struct agg_table *rib_route_table, /* preload NVE rib table */ struct prefix *pfx_target_original); /* query target */ extern struct rfapi_import_table *rfapiMacImportTableGetNoAlloc(struct bgp *bgp, diff --git a/bgpd/rfapi/rfapi_monitor.c b/bgpd/rfapi/rfapi_monitor.c index 30182ba7a6..59387240fa 100644 --- a/bgpd/rfapi/rfapi_monitor.c +++ b/bgpd/rfapi/rfapi_monitor.c @@ -28,7 +28,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/vty.h" #include "lib/memory.h" #include "lib/log.h" @@ -68,10 +68,10 @@ static void rfapiMonitorEthDetachImport(struct bgp *bgp, /* * Debug function, special case */ -void rfapiMonitorEthSlCheck(struct route_node *rn, const char *tag1, +void rfapiMonitorEthSlCheck(struct agg_node *rn, const char *tag1, const char *tag2) { - struct route_node *rn_saved = NULL; + struct agg_node *rn_saved = NULL; static struct skiplist *sl_saved = NULL; struct skiplist *sl; @@ -118,12 +118,13 @@ void rfapiMonitorDupCheck(struct bgp *bgp) struct rfapi_descriptor *rfd; for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) { - struct route_node *mrn; + struct agg_node *mrn; if (!rfd->mon) continue; - for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) { + for (mrn = agg_route_top(rfd->mon); mrn; + mrn = agg_route_next(mrn)) { struct rfapi_monitor_vpn *m; for (m = (struct rfapi_monitor_vpn *)(mrn->info); m; m = m->next) @@ -132,12 +133,13 @@ void rfapiMonitorDupCheck(struct bgp *bgp) } for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) { - struct route_node *mrn; + struct agg_node *mrn; if (!rfd->mon) continue; - for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) { + for (mrn = agg_route_top(rfd->mon); mrn; + mrn = agg_route_next(mrn)) { struct rfapi_monitor_vpn *m; for (m = (struct rfapi_monitor_vpn *)(mrn->info); m; @@ -158,15 +160,17 @@ void rfapiMonitorCleanCheck(struct bgp *bgp) assert(!rfd->import_table->vpn0_queries[AFI_IP]); assert(!rfd->import_table->vpn0_queries[AFI_IP6]); - struct route_node *rn; + struct agg_node *rn; - for (rn = route_top(rfd->import_table->imported_vpn[AFI_IP]); - rn; rn = route_next(rn)) { + for (rn = agg_route_top( + rfd->import_table->imported_vpn[AFI_IP]); + rn; rn = agg_route_next(rn)) { assert(!RFAPI_MONITOR_VPN(rn)); } - for (rn = route_top(rfd->import_table->imported_vpn[AFI_IP6]); - rn; rn = route_next(rn)) { + for (rn = agg_route_top( + rfd->import_table->imported_vpn[AFI_IP6]); + rn; rn = agg_route_next(rn)) { assert(!RFAPI_MONITOR_VPN(rn)); } @@ -180,7 +184,7 @@ void rfapiMonitorCheckAttachAllowed(void) assert(!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)); } -void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn) +void rfapiMonitorExtraFlush(safi_t safi, struct agg_node *rn) { struct rfapi_it_extra *hie; struct rfapi_monitor_vpn *v; @@ -202,7 +206,7 @@ void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn) e_next = e->next; e->next = NULL; XFREE(MTYPE_RFAPI_MONITOR_ENCAP, e); - route_unlock_node(rn); + agg_unlock_node(rn); } hie->u.encap.e = NULL; break; @@ -212,33 +216,33 @@ void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn) v_next = v->next; v->next = NULL; XFREE(MTYPE_RFAPI_MONITOR, e); - route_unlock_node(rn); + agg_unlock_node(rn); } hie->u.vpn.v = NULL; if (hie->u.vpn.e.source) { while (!skiplist_delete_first(hie->u.vpn.e.source)) { - route_unlock_node(rn); + agg_unlock_node(rn); } skiplist_free(hie->u.vpn.e.source); hie->u.vpn.e.source = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } if (hie->u.vpn.idx_rd) { /* looping through bi->extra->vnc.import.rd is tbd */ while (!skiplist_delete_first(hie->u.vpn.idx_rd)) { - route_unlock_node(rn); + agg_unlock_node(rn); } skiplist_free(hie->u.vpn.idx_rd); hie->u.vpn.idx_rd = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } if (hie->u.vpn.mon_eth) { while (!skiplist_delete_first(hie->u.vpn.mon_eth)) { - route_unlock_node(rn); + agg_unlock_node(rn); } skiplist_free(hie->u.vpn.mon_eth); hie->u.vpn.mon_eth = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } break; @@ -247,13 +251,13 @@ void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn) } XFREE(MTYPE_RFAPI_IT_EXTRA, hie); rn->aggregate = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } /* * If the child lists are empty, release the rfapi_it_extra struct */ -void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn) +void rfapiMonitorExtraPrune(safi_t safi, struct agg_node *rn) { struct rfapi_it_extra *hie; @@ -279,28 +283,28 @@ void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn) return; skiplist_free(hie->u.vpn.mon_eth); hie->u.vpn.mon_eth = NULL; - route_unlock_node(rn); /* uncount skiplist */ + agg_unlock_node(rn); /* uncount skiplist */ } if (hie->u.vpn.e.source) { if (skiplist_count(hie->u.vpn.e.source)) return; skiplist_free(hie->u.vpn.e.source); hie->u.vpn.e.source = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } if (hie->u.vpn.idx_rd) { if (skiplist_count(hie->u.vpn.idx_rd)) return; skiplist_free(hie->u.vpn.idx_rd); hie->u.vpn.idx_rd = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } if (hie->u.vpn.mon_eth) { if (skiplist_count(hie->u.vpn.mon_eth)) return; skiplist_free(hie->u.vpn.mon_eth); hie->u.vpn.mon_eth = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } break; @@ -309,17 +313,17 @@ void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn) } XFREE(MTYPE_RFAPI_IT_EXTRA, hie); rn->aggregate = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } /* * returns locked node */ -struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, - struct prefix *p) +struct agg_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, + struct prefix *p) { afi_t afi; - struct route_node *rn; + struct agg_node *rn; if (RFAPI_0_PREFIX(p)) { assert(1); @@ -341,7 +345,7 @@ struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, * if a monitor is moved to another node, there must be * corresponding unlock/locks */ - for (rn = route_node_match(rfd->import_table->imported_vpn[afi], p); + for (rn = agg_node_match(rfd->import_table->imported_vpn[afi], p); rn;) { struct bgp_info *bi; @@ -369,9 +373,9 @@ struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, if (bi) break; - route_unlock_node(rn); - if ((rn = rn->parent)) { - route_lock_node(rn); + agg_unlock_node(rn); + if ((rn = agg_node_parent(rn))) { + agg_lock_node(rn); } } @@ -383,8 +387,8 @@ struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, /* creates default node if none exists, and increments ref count */ - rn = route_node_get(rfd->import_table->imported_vpn[afi], - &pfx_default); + rn = agg_node_get(rfd->import_table->imported_vpn[afi], + &pfx_default); } return rn; @@ -396,10 +400,10 @@ struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, * returned (for the benefit of caller which might like to use it * to generate an immediate query response). */ -static struct route_node *rfapiMonitorAttachImport(struct rfapi_descriptor *rfd, - struct rfapi_monitor_vpn *m) +static struct agg_node *rfapiMonitorAttachImport(struct rfapi_descriptor *rfd, + struct rfapi_monitor_vpn *m) { - struct route_node *rn; + struct agg_node *rn; rfapiMonitorCheckAttachAllowed(); @@ -438,7 +442,7 @@ static struct route_node *rfapiMonitorAttachImport(struct rfapi_descriptor *rfd, */ void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd) { - struct route_node *mrn; + struct agg_node *mrn; if (!rfd->mon) { /* @@ -447,7 +451,7 @@ void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd) return; } - for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) { + for (mrn = agg_route_top(rfd->mon); mrn; mrn = agg_route_next(mrn)) { if (!mrn->info) continue; @@ -467,11 +471,11 @@ void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd) * are disabled, this function will not perform a lookup, and the * caller will have to do its own lookup. */ -struct route_node * -rfapiMonitorAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *p) +struct agg_node *rfapiMonitorAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct prefix *p) { struct rfapi_monitor_vpn *m; - struct route_node *rn; + struct agg_node *rn; /* * Initialize nve's monitor list if needed @@ -480,15 +484,15 @@ rfapiMonitorAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *p) * or be 0/0 so they won't get mixed up. */ if (!rfd->mon) { - rfd->mon = route_table_init(); + rfd->mon = agg_table_init(); } - rn = route_node_get(rfd->mon, p); + rn = agg_node_get(rfd->mon, p); if (rn->info) { /* * received this query before, no further action needed */ rfapiMonitorTimerRestart((struct rfapi_monitor_vpn *)rn->info); - route_unlock_node(rn); + agg_unlock_node(rn); return NULL; } @@ -575,7 +579,7 @@ rfapiMonitorDetachImport(struct rfapi_monitor_vpn *m) this->next; } RFAPI_CHECK_REFCOUNT(m->node, SAFI_MPLS_VPN, 1); - route_unlock_node(m->node); + agg_unlock_node(m->node); } m->node = NULL; } @@ -586,12 +590,12 @@ rfapiMonitorDetachImport(struct rfapi_monitor_vpn *m) void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd) { - struct route_node *rn; + struct agg_node *rn; if (!rfd->mon) return; - for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rfd->mon); rn; rn = agg_route_next(rn)) { if (rn->info) { rfapiMonitorDetachImport( (struct rfapi_monitor_vpn *)(rn->info)); @@ -602,11 +606,11 @@ void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd) void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *p) { - struct route_node *rn; + struct agg_node *rn; struct rfapi_monitor_vpn *m; assert(rfd->mon); - rn = route_node_get(rfd->mon, p); /* locks node */ + rn = agg_node_get(rfd->mon, p); /* locks node */ m = rn->info; assert(m); @@ -628,8 +632,8 @@ void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd, */ XFREE(MTYPE_RFAPI_MONITOR, m); rn->info = NULL; - route_unlock_node(rn); /* undo original lock when created */ - route_unlock_node(rn); /* undo lock in route_node_get */ + agg_unlock_node(rn); /* undo original lock when created */ + agg_unlock_node(rn); /* undo lock in agg_node_get */ --rfd->monitor_count; --bgp->rfapi->monitor_count; @@ -640,7 +644,7 @@ void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd, */ int rfapiMonitorDelHd(struct rfapi_descriptor *rfd) { - struct route_node *rn; + struct agg_node *rn; struct bgp *bgp; int count = 0; @@ -649,7 +653,8 @@ int rfapiMonitorDelHd(struct rfapi_descriptor *rfd) bgp = bgp_get_default(); if (rfd->mon) { - for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rfd->mon); rn; + rn = agg_route_next(rn)) { struct rfapi_monitor_vpn *m; if ((m = rn->info)) { if (!(bgp->rfapi_cfg->flags @@ -664,14 +669,14 @@ int rfapiMonitorDelHd(struct rfapi_descriptor *rfd) XFREE(MTYPE_RFAPI_MONITOR, m); rn->info = NULL; - route_unlock_node(rn); /* undo original lock + agg_unlock_node(rn); /* undo original lock when created */ ++count; --rfd->monitor_count; --bgp->rfapi->monitor_count; } } - route_table_finish(rfd->mon); + agg_table_finish(rfd->mon); rfd->mon = NULL; } @@ -788,7 +793,7 @@ static void rfapiMonitorTimerRestart(struct rfapi_monitor_vpn *m) */ void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, struct prefix *p) { - struct route_node *rn; + struct agg_node *rn; if (AF_ETHERNET == p->family) { struct rfapi_monitor_eth *mon_eth; @@ -812,7 +817,8 @@ void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, struct prefix *p) } } else { - for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rfd->mon); rn; + rn = agg_route_next(rn)) { struct rfapi_monitor_vpn *m; if (!((m = rn->info))) @@ -831,11 +837,11 @@ void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, struct prefix *p) * rfapiRibUpdatePendingNode with this node and all corresponding NVEs. */ void rfapiMonitorItNodeChanged( - struct rfapi_import_table *import_table, struct route_node *it_node, + struct rfapi_import_table *import_table, struct agg_node *it_node, struct rfapi_monitor_vpn *monitor_list) /* for base it node, NULL=all */ { struct skiplist *nves_seen; - struct route_node *rn = it_node; + struct agg_node *rn = it_node; struct bgp *bgp = bgp_get_default(); afi_t afi = family2afi(rn->p.family); #if DEBUG_L2_EXTRA @@ -909,7 +915,8 @@ void rfapiMonitorItNodeChanged( * to them * because we haven't sent them an initial route. */ - if (!rn->parent && !rn->info && it_node->parent) + if (!agg_node_parent(rn) && !rn->info + && it_node->parent) break; for (; m; m = m->next) { @@ -947,7 +954,7 @@ void rfapiMonitorItNodeChanged( m->rfd->response_lifetime); } } - rn = rn->parent; + rn = agg_node_parent(rn); if (rn) m = RFAPI_MONITOR_VPN(rn); } while (rn); @@ -1023,8 +1030,7 @@ void rfapiMonitorItNodeChanged( * omit old node and its subtree */ void rfapiMonitorMovedUp(struct rfapi_import_table *import_table, - struct route_node *old_node, - struct route_node *new_node, + struct agg_node *old_node, struct agg_node *new_node, struct rfapi_monitor_vpn *monitor_list) { struct bgp *bgp = bgp_get_default(); @@ -1125,7 +1131,7 @@ static int mon_eth_cmp(void *a, void *b) static void rfapiMonitorEthAttachImport( struct rfapi_import_table *it, - struct route_node *rn, /* it node attach point if non-0 */ + struct agg_node *rn, /* it node attach point if non-0 */ struct rfapi_monitor_eth *mon) /* monitor struct to attach */ { struct skiplist *sl; @@ -1162,7 +1168,7 @@ static void rfapiMonitorEthAttachImport( if (!sl) { sl = RFAPI_MONITOR_ETH_W_ALLOC(rn) = skiplist_new(0, NULL, NULL); - route_lock_node(rn); /* count skiplist mon_eth */ + agg_lock_node(rn); /* count skiplist mon_eth */ } #if DEBUG_L2_EXTRA @@ -1175,7 +1181,7 @@ static void rfapiMonitorEthAttachImport( assert(!rc); /* count eth monitor */ - route_lock_node(rn); + agg_lock_node(rn); } /* @@ -1202,7 +1208,7 @@ static void rfapiMonitorEthAttachImportHd(struct bgp *bgp, struct rfapi_import_table *it; struct prefix pfx_mac_buf; - struct route_node *rn; + struct agg_node *rn; it = rfapiMacImportTableGet(bgp, mon->logical_net_id); assert(it); @@ -1212,7 +1218,7 @@ static void rfapiMonitorEthAttachImportHd(struct bgp *bgp, pfx_mac_buf.prefixlen = 48; pfx_mac_buf.u.prefix_eth = mon->macaddr; - rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); + rn = agg_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); assert(rn); (void)rfapiMonitorEthAttachImport(it, rn, mon); @@ -1226,7 +1232,7 @@ static void rfapiMonitorEthDetachImport( struct rfapi_import_table *it; struct prefix pfx_mac_buf; struct skiplist *sl; - struct route_node *rn; + struct agg_node *rn; int rc; it = rfapiMacImportTableGet(bgp, mon->logical_net_id); @@ -1262,7 +1268,7 @@ static void rfapiMonitorEthDetachImport( pfx_mac_buf.prefixlen = 48; pfx_mac_buf.u.prefix_eth = mon->macaddr; - rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); + rn = agg_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); assert(rn); #if DEBUG_L2_EXTRA @@ -1288,19 +1294,19 @@ static void rfapiMonitorEthDetachImport( assert(!rc); /* uncount eth monitor */ - route_unlock_node(rn); + agg_unlock_node(rn); } -struct route_node *rfapiMonitorEthAdd(struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct ethaddr *macaddr, - uint32_t logical_net_id) +struct agg_node *rfapiMonitorEthAdd(struct bgp *bgp, + struct rfapi_descriptor *rfd, + struct ethaddr *macaddr, + uint32_t logical_net_id) { int rc; struct rfapi_monitor_eth mon_buf; struct rfapi_monitor_eth *val; struct rfapi_import_table *it; - struct route_node *rn = NULL; + struct agg_node *rn = NULL; struct prefix pfx_mac_buf; if (!rfd->mon_eth) { @@ -1323,7 +1329,7 @@ struct route_node *rfapiMonitorEthAdd(struct bgp *bgp, pfx_mac_buf.u.prefix_eth = *macaddr; if (!RFAPI_0_ETHERADDR(macaddr)) { - rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); + rn = agg_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); assert(rn); } @@ -1453,8 +1459,8 @@ void rfapiMonitorCallbacksOff(struct bgp *bgp) { struct rfapi_import_table *it; afi_t afi; - struct route_table *rt; - struct route_node *rn; + struct agg_table *rt; + struct agg_node *rn; void *cursor; int rc; struct rfapi *h = bgp->rfapi; @@ -1485,7 +1491,8 @@ void rfapiMonitorCallbacksOff(struct bgp *bgp) rt = it->imported_vpn[afi]; - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; + rn = agg_route_next(rn)) { m = RFAPI_MONITOR_VPN(rn); if (RFAPI_MONITOR_VPN(rn)) RFAPI_MONITOR_VPN_W_ALLOC(rn) = NULL; @@ -1494,7 +1501,7 @@ void rfapiMonitorCallbacksOff(struct bgp *bgp) m->next = NULL; /* gratuitous safeness */ m->node = NULL; - route_unlock_node(rn); /* uncount */ + agg_unlock_node(rn); /* uncount */ } } @@ -1531,12 +1538,12 @@ void rfapiMonitorCallbacksOff(struct bgp *bgp) * Find non-0 monitors (i.e., actual addresses, not FTD * monitors) */ - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) { struct skiplist *sl; sl = RFAPI_MONITOR_ETH(rn); while (!skiplist_delete_first(sl)) { - route_unlock_node(rn); /* uncount monitor */ + agg_unlock_node(rn); /* uncount monitor */ } } diff --git a/bgpd/rfapi/rfapi_monitor.h b/bgpd/rfapi/rfapi_monitor.h index edc9744cdb..9b85f6248e 100644 --- a/bgpd/rfapi/rfapi_monitor.h +++ b/bgpd/rfapi/rfapi_monitor.h @@ -30,10 +30,10 @@ * to indicate which nves are interested in a prefix/target */ struct rfapi_monitor_vpn { - struct rfapi_monitor_vpn *next; /* chain from struct route_node */ + struct rfapi_monitor_vpn *next; /* chain from struct agg_node */ struct rfapi_descriptor *rfd; /* which NVE requested the route */ struct prefix p; /* constant: pfx in original request */ - struct route_node *node; /* node we're currently attached to */ + struct agg_node *node; /* node we're currently attached to */ uint32_t flags; #define RFAPI_MON_FLAG_NEEDCALLBACK 0x00000001 /* deferred callback */ @@ -44,9 +44,9 @@ struct rfapi_monitor_vpn { struct rfapi_monitor_encap { struct rfapi_monitor_encap *next; struct rfapi_monitor_encap *prev; - struct route_node *node; /* VPN node */ + struct agg_node *node; /* VPN node */ struct bgp_info *bi; /* VPN bi */ - struct route_node *rn; /* parent node */ + struct agg_node *rn; /* parent node */ }; struct rfapi_monitor_eth { @@ -98,7 +98,7 @@ struct rfapi_it_extra { ((struct rfapi_it_extra \ *)((rn)->aggregate \ ? (rn)->aggregate \ - : (route_lock_node(rn), \ + : (agg_lock_node(rn), \ (rn)->aggregate = XCALLOC( \ MTYPE_RFAPI_IT_EXTRA, \ sizeof(struct rfapi_it_extra))))) @@ -138,16 +138,16 @@ extern void rfapiMonitorCleanCheck(struct bgp *bgp); extern void rfapiMonitorCheckAttachAllowed(void); -extern void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn); +extern void rfapiMonitorExtraFlush(safi_t safi, struct agg_node *rn); -extern struct route_node * -rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, struct prefix *p); +extern struct agg_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, + struct prefix *p); extern void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd); -extern struct route_node *rfapiMonitorAdd(struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *p); +extern struct agg_node *rfapiMonitorAdd(struct bgp *bgp, + struct rfapi_descriptor *rfd, + struct prefix *p); extern void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd); @@ -164,24 +164,24 @@ extern void rfapiMonitorResponseRemovalOff(struct bgp *bgp); extern void rfapiMonitorResponseRemovalOn(struct bgp *bgp); -extern void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn); +extern void rfapiMonitorExtraPrune(safi_t safi, struct agg_node *rn); extern void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, struct prefix *p); extern void rfapiMonitorItNodeChanged(struct rfapi_import_table *import_table, - struct route_node *it_node, + struct agg_node *it_node, struct rfapi_monitor_vpn *monitor_list); extern void rfapiMonitorMovedUp(struct rfapi_import_table *import_table, - struct route_node *old_node, - struct route_node *new_node, + struct agg_node *old_node, + struct agg_node *new_node, struct rfapi_monitor_vpn *monitor_list); -extern struct route_node *rfapiMonitorEthAdd(struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct ethaddr *macaddr, - uint32_t logical_net_id); +extern struct agg_node *rfapiMonitorEthAdd(struct bgp *bgp, + struct rfapi_descriptor *rfd, + struct ethaddr *macaddr, + uint32_t logical_net_id); extern void rfapiMonitorEthDel(struct bgp *bgp, struct rfapi_descriptor *rfd, struct ethaddr *macaddr, diff --git a/bgpd/rfapi/rfapi_nve_addr.c b/bgpd/rfapi/rfapi_nve_addr.c index 0fb887912c..ee54d88c3f 100644 --- a/bgpd/rfapi/rfapi_nve_addr.c +++ b/bgpd/rfapi/rfapi_nve_addr.c @@ -21,7 +21,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/vty.h" #include "lib/memory.h" #include "lib/skiplist.h" diff --git a/bgpd/rfapi/rfapi_private.h b/bgpd/rfapi/rfapi_private.h index 9c759fc47e..4d8072a49b 100644 --- a/bgpd/rfapi/rfapi_private.h +++ b/bgpd/rfapi/rfapi_private.h @@ -47,7 +47,7 @@ struct rfapi_advertised_prefixes { }; struct rfapi_descriptor { - struct route_node *un_node; /* backref to un table */ + struct agg_node *un_node; /* backref to un table */ struct rfapi_descriptor *next; /* next vn_addr */ @@ -76,7 +76,7 @@ struct rfapi_descriptor { struct rfapi_import_table *import_table; uint32_t monitor_count; - struct route_table *mon; /* rfapi_monitors */ + struct agg_table *mon; /* rfapi_monitors */ struct skiplist *mon_eth; /* ethernet monitors */ /* @@ -85,10 +85,10 @@ struct rfapi_descriptor { * rsp_times last time we sent response containing pfx */ uint32_t rib_prefix_count; /* pfxes with routes */ - struct route_table *rib[AFI_MAX]; - struct route_table *rib_pending[AFI_MAX]; + struct agg_table *rib[AFI_MAX]; + struct agg_table *rib_pending[AFI_MAX]; struct work_queue *updated_responses_queue; - struct route_table *rsp_times[AFI_MAX]; + struct agg_table *rsp_times[AFI_MAX]; uint32_t rsp_counter; /* dedup initial rsp */ time_t rsp_time; /* dedup initial rsp */ @@ -171,7 +171,7 @@ struct rfapi_global_stats { * check vn address to get exact match. */ struct rfapi { - struct route_table *un[AFI_MAX]; + struct agg_table *un[AFI_MAX]; struct rfapi_import_table *imports; /* IPv4, IPv6 */ struct list descriptors; /* debug & resolve-nve imports */ @@ -198,8 +198,8 @@ struct rfapi { * bgp unicast or zebra, we need to keep track of information * related to expiring the routes according to the VNC lifetime */ - struct route_table *rt_export_bgp[AFI_MAX]; - struct route_table *rt_export_zebra[AFI_MAX]; + struct agg_table *rt_export_bgp[AFI_MAX]; + struct agg_table *rt_export_zebra[AFI_MAX]; /* * For VNC->BGP unicast exports in CE mode, we need a diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 60534fece0..3ac217ff89 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -27,7 +27,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/vty.h" #include "lib/memory.h" #include "lib/log.h" @@ -150,10 +150,10 @@ void rfapiRibCheckCounts( for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - struct route_node *rn; + struct agg_node *rn; - for (rn = route_top(rfd->rib[afi]); rn; - rn = route_next(rn)) { + for (rn = agg_route_top(rfd->rib[afi]); rn; + rn = agg_route_next(rn)) { struct skiplist *sl = rn->info; struct skiplist *dsl = rn->aggregate; @@ -175,8 +175,8 @@ void rfapiRibCheckCounts( ++t_pfx_deleted; } } - for (rn = route_top(rfd->rib_pending[afi]); rn; - rn = route_next(rn)) { + for (rn = agg_route_top(rfd->rib_pending[afi]); rn; + rn = agg_route_next(rn)) { struct list *l = rn->info; /* sorted by cost */ struct skiplist *sl = rn->aggregate; @@ -286,7 +286,7 @@ struct rfapi_rib_tcb { struct rfapi_descriptor *rfd; struct skiplist *sl; struct rfapi_info *ri; - struct route_node *rn; + struct agg_node *rn; int flags; #define RFAPI_RIB_TCB_FLAG_DELETED 0x00000001 }; @@ -325,7 +325,7 @@ static int rfapiRibExpireTimer(struct thread *t) RFAPI_RIB_PREFIX_COUNT_DECR(tcb->rfd, bgp->rfapi); } skiplist_free(tcb->sl); - route_unlock_node(tcb->rn); + agg_unlock_node(tcb->rn); } XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); @@ -335,10 +335,10 @@ static int rfapiRibExpireTimer(struct thread *t) return 0; } -static void -rfapiRibStartTimer(struct rfapi_descriptor *rfd, struct rfapi_info *ri, - struct route_node *rn, /* route node attached to */ - int deleted) +static void rfapiRibStartTimer(struct rfapi_descriptor *rfd, + struct rfapi_info *ri, + struct agg_node *rn, /* route node attached to */ + int deleted) { struct thread *t = ri->timer; struct rfapi_rib_tcb *tcb = NULL; @@ -486,12 +486,12 @@ void rfapiRibClear(struct rfapi_descriptor *rfd) #endif for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - struct route_node *pn; - struct route_node *rn; + struct agg_node *pn; + struct agg_node *rn; if (rfd->rib_pending[afi]) { - for (pn = route_top(rfd->rib_pending[afi]); pn; - pn = route_next(pn)) { + for (pn = agg_route_top(rfd->rib_pending[afi]); pn; + pn = agg_route_next(pn)) { if (pn->aggregate) { /* * free references into the rfapi_info @@ -502,7 +502,7 @@ void rfapiRibClear(struct rfapi_descriptor *rfd) (struct skiplist *)(pn->aggregate)); pn->aggregate = NULL; - route_unlock_node( + agg_unlock_node( pn); /* skiplist deleted */ } /* @@ -516,13 +516,13 @@ void rfapiRibClear(struct rfapi_descriptor *rfd) } pn->info = NULL; /* linklist or 1 deleted */ - route_unlock_node(pn); + agg_unlock_node(pn); } } } if (rfd->rib[afi]) { - for (rn = route_top(rfd->rib[afi]); rn; - rn = route_next(rn)) { + for (rn = agg_route_top(rfd->rib[afi]); rn; + rn = agg_route_next(rn)) { if (rn->info) { struct rfapi_info *ri; @@ -541,7 +541,7 @@ void rfapiRibClear(struct rfapi_descriptor *rfd) skiplist_free( (struct skiplist *)rn->info); rn->info = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); RFAPI_RIB_PREFIX_COUNT_DECR(rfd, bgp->rfapi); } @@ -566,7 +566,7 @@ void rfapiRibClear(struct rfapi_descriptor *rfd) *)(rn->aggregate)); rn->aggregate = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } } } @@ -601,15 +601,18 @@ void rfapiRibFree(struct rfapi_descriptor *rfd) * Free radix trees */ for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - route_table_finish(rfd->rib_pending[afi]); + if (rfd->rib_pending[afi]) + agg_table_finish(rfd->rib_pending[afi]); rfd->rib_pending[afi] = NULL; - route_table_finish(rfd->rib[afi]); + if (rfd->rib[afi]) + agg_table_finish(rfd->rib[afi]); rfd->rib[afi] = NULL; - /* NB route_table_finish frees only prefix nodes, not chained + /* NB agg_table_finish frees only prefix nodes, not chained * info */ - route_table_finish(rfd->rsp_times[afi]); + if (rfd->rsp_times[afi]) + agg_table_finish(rfd->rsp_times[afi]); rfd->rib[afi] = NULL; } } @@ -730,7 +733,7 @@ static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri, * !0 do not include route in response */ int rfapiRibPreloadBi( - struct route_node *rfd_rib_node, /* NULL = don't preload or filter */ + struct agg_node *rfd_rib_node, /* NULL = don't preload or filter */ struct prefix *pfx_vn, struct prefix *pfx_un, uint32_t lifetime, struct bgp_info *bi) { @@ -738,7 +741,7 @@ int rfapiRibPreloadBi( struct skiplist *slRibPt = NULL; struct rfapi_info *ori = NULL; struct rfapi_rib_key rk; - struct route_node *trn; + struct agg_node *trn; afi_t afi; if (!rfd_rib_node) @@ -746,7 +749,7 @@ int rfapiRibPreloadBi( afi = family2afi(rfd_rib_node->p.family); - rfd = (struct rfapi_descriptor *)(rfd_rib_node->table->info); + rfd = agg_get_table_info(agg_get_table(rfd_rib_node)); memset((void *)&rk, 0, sizeof(rk)); rk.vn = *pfx_vn; @@ -784,7 +787,7 @@ int rfapiRibPreloadBi( if (!slRibPt) { slRibPt = skiplist_new(0, rfapi_rib_key_cmp, NULL); rfd_rib_node->info = slRibPt; - route_lock_node(rfd_rib_node); + agg_lock_node(rfd_rib_node); RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfd->bgp->rfapi); } skiplist_insert(slRibPt, &ori->rk, ori); @@ -802,11 +805,11 @@ int rfapiRibPreloadBi( /* * Update last sent time for prefix */ - trn = route_node_get(rfd->rsp_times[afi], - &rfd_rib_node->p); /* locks trn */ + trn = agg_node_get(rfd->rsp_times[afi], + &rfd_rib_node->p); /* locks trn */ trn->info = (void *)(uintptr_t)bgp_clock(); if (trn->lock > 1) - route_unlock_node(trn); + agg_unlock_node(trn); return 0; } @@ -837,7 +840,7 @@ int rfapiRibPreloadBi( */ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, afi_t afi, - struct route_node *pn, /* pending node */ + struct agg_node *pn, /* pending node */ struct rfapi_next_hop_entry **head, struct rfapi_next_hop_entry **tail) { @@ -845,7 +848,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, struct listnode *nnode = NULL; struct rfapi_info *ri = NULL; /* happy valgrind */ struct rfapi_ip_prefix hp = {0}; /* pfx to put in NHE */ - struct route_node *rn = NULL; + struct agg_node *rn = NULL; struct skiplist *slRibPt = NULL; /* rib list */ struct skiplist *slPendPt = NULL; struct list *lPendCost = NULL; @@ -875,7 +878,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, /* * Find corresponding RIB node */ - rn = route_node_get(rfd->rib[afi], &pn->p); /* locks rn */ + rn = agg_node_get(rfd->rib[afi], &pn->p); /* locks rn */ /* * RIB skiplist has key=rfapi_addr={vn,un}, val = rfapi_info, @@ -945,30 +948,30 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, skiplist_free(slRibPt); rn->info = slRibPt = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); lPendCost = pn->info = NULL; - route_unlock_node(pn); + agg_unlock_node(pn); goto callback; } if (slRibPt) { skiplist_free(slRibPt); rn->info = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } assert(!slPendPt); if (slPendPt) { /* TBD I think we can toss this block */ skiplist_free(slPendPt); pn->aggregate = NULL; - route_unlock_node(pn); + agg_unlock_node(pn); } pn->info = NULL; - route_unlock_node(pn); + agg_unlock_node(pn); - route_unlock_node(rn); /* route_node_get() */ + agg_unlock_node(rn); /* agg_node_get() */ if (rib_node_started_nonempty) { RFAPI_RIB_PREFIX_COUNT_DECR(rfd, bgp->rfapi); @@ -1076,7 +1079,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, if (skiplist_empty(slRibPt)) { skiplist_free(slRibPt); slRibPt = rn->info = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } } } @@ -1142,7 +1145,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, slRibPt = skiplist_new( 0, rfapi_rib_key_cmp, NULL); rn->info = slRibPt; - route_lock_node(rn); + agg_lock_node(rn); } skiplist_insert(slRibPt, &ori->rk, ori); @@ -1192,7 +1195,7 @@ callback: for (ALL_LIST_ELEMENTS(lPendCost, node, nnode, ri)) { struct rfapi_next_hop_entry *new; - struct route_node *trn; + struct agg_node *trn; new = XCALLOC(MTYPE_RFAPI_NEXTHOP, sizeof(struct rfapi_next_hop_entry)); @@ -1244,11 +1247,11 @@ callback: /* * update this NVE's timestamp for this prefix */ - trn = route_node_get(rfd->rsp_times[afi], - &pn->p); /* locks trn */ + trn = agg_node_get(rfd->rsp_times[afi], + &pn->p); /* locks trn */ trn->info = (void *)(uintptr_t)bgp_clock(); if (trn->lock > 1) - route_unlock_node(trn); + agg_unlock_node(trn); rfapiRfapiIpAddr2Str(&new->vn_address, buf, BUFSIZ); rfapiRfapiIpAddr2Str(&new->un_address, buf2, BUFSIZ); @@ -1347,7 +1350,7 @@ callback: 0, rfapi_rib_key_cmp, (void (*)(void *)) rfapi_info_free); - route_lock_node(rn); + agg_lock_node(rn); } RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); @@ -1438,18 +1441,18 @@ callback: RFAPI_RIB_CHECK_COUNTS(0, 0); /* - * Reset pending lists. The final route_unlock_node() will probably + * Reset pending lists. The final agg_unlock_node() will probably * cause the pending node to be released. */ if (slPendPt) { skiplist_free(slPendPt); pn->aggregate = NULL; - route_unlock_node(pn); + agg_unlock_node(pn); } if (lPendCost) { list_delete_and_null(&lPendCost); pn->info = NULL; - route_unlock_node(pn); + agg_unlock_node(pn); } RFAPI_RIB_CHECK_COUNTS(0, 0); @@ -1466,7 +1469,7 @@ callback: if (sendingsomeroutes) rfapiMonitorTimersRestart(rfd, &pn->p); - route_unlock_node(rn); /* route_node_get() */ + agg_unlock_node(rn); /* agg_node_get() */ RFAPI_RIB_CHECK_COUNTS(1, 0); } @@ -1484,7 +1487,7 @@ static void rib_do_callback_onepass(struct rfapi_descriptor *rfd, afi_t afi) struct bgp *bgp = bgp_get_default(); struct rfapi_next_hop_entry *head = NULL; struct rfapi_next_hop_entry *tail = NULL; - struct route_node *rn; + struct agg_node *rn; #if DEBUG_L2_EXTRA vnc_zlog_debug_verbose("%s: rfd=%p, afi=%d", __func__, rfd, afi); @@ -1495,7 +1498,8 @@ static void rib_do_callback_onepass(struct rfapi_descriptor *rfd, afi_t afi) assert(bgp->rfapi); - for (rn = route_top(rfd->rib_pending[afi]); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rfd->rib_pending[afi]); rn; + rn = agg_route_next(rn)) { process_pending_node(bgp, rfd, afi, rn, &head, &tail); } @@ -1585,11 +1589,11 @@ static void updated_responses_queue_init(struct rfapi_descriptor *rfd) void rfapiRibUpdatePendingNode( struct bgp *bgp, struct rfapi_descriptor *rfd, struct rfapi_import_table *it, /* needed for L2 */ - struct route_node *it_node, uint32_t lifetime) + struct agg_node *it_node, uint32_t lifetime) { struct prefix *prefix; struct bgp_info *bi; - struct route_node *pn; + struct agg_node *pn; afi_t afi; uint32_t queued_flag; int count = 0; @@ -1609,7 +1613,7 @@ void rfapiRibUpdatePendingNode( prefix2str(prefix, buf, sizeof(buf)); vnc_zlog_debug_verbose("%s: prefix=%s", __func__, buf); - pn = route_node_get(rfd->rib_pending[afi], prefix); + pn = agg_node_get(rfd->rib_pending[afi], prefix); assert(pn); vnc_zlog_debug_verbose("%s: pn->info=%p, pn->aggregate=%p", __func__, @@ -1622,7 +1626,7 @@ void rfapiRibUpdatePendingNode( */ skiplist_free((struct skiplist *)(pn->aggregate)); pn->aggregate = NULL; - route_unlock_node(pn); /* skiplist deleted */ + agg_unlock_node(pn); /* skiplist deleted */ } @@ -1634,7 +1638,7 @@ void rfapiRibUpdatePendingNode( list_delete_and_null((struct list **)(&pn->info)); } pn->info = NULL; - route_unlock_node(pn); /* linklist or 1 deleted */ + agg_unlock_node(pn); /* linklist or 1 deleted */ } /* @@ -1689,7 +1693,7 @@ void rfapiRibUpdatePendingNode( if (!pn->aggregate) { pn->aggregate = skiplist_new(0, rfapi_rib_key_cmp, NULL); - route_lock_node(pn); + agg_lock_node(pn); } /* @@ -1715,7 +1719,7 @@ void rfapiRibUpdatePendingNode( pn->info = list_new(); ((struct list *)(pn->info))->del = (void (*)(void *))rfapi_info_free; - route_lock_node(pn); + agg_lock_node(pn); } listnode_add((struct list *)(pn->info), ri); @@ -1730,10 +1734,10 @@ void rfapiRibUpdatePendingNode( assert(!pn->aggregate); pn->info = (void *)1; /* magic value means this node has no routes */ - route_lock_node(pn); + agg_lock_node(pn); } - route_unlock_node(pn); /* route_node_get */ + agg_unlock_node(pn); /* agg_node_get */ queued_flag = RFAPI_QUEUED_FLAG(afi); @@ -1757,25 +1761,30 @@ void rfapiRibUpdatePendingNode( void rfapiRibUpdatePendingNodeSubtree( struct bgp *bgp, struct rfapi_descriptor *rfd, - struct rfapi_import_table *it, struct route_node *it_node, - struct route_node *omit_subtree, /* may be NULL */ + struct rfapi_import_table *it, struct agg_node *it_node, + struct agg_node *omit_subtree, /* may be NULL */ uint32_t lifetime) { /* FIXME: need to find a better way here to work without sticking our * hands in node->link */ - if (it_node->l_left && (it_node->l_left != omit_subtree)) { - if (it_node->l_left->info) - rfapiRibUpdatePendingNode(bgp, rfd, it, it_node->l_left, - lifetime); - rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, it_node->l_left, + if (agg_node_left(it_node) + && (agg_node_left(it_node) != omit_subtree)) { + if (agg_node_left(it_node)->info) + rfapiRibUpdatePendingNode( + bgp, rfd, it, agg_node_left(it_node), lifetime); + rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, + agg_node_left(it_node), omit_subtree, lifetime); } - if (it_node->l_right && (it_node->l_right != omit_subtree)) { - if (it_node->l_right->info) + if (agg_node_right(it_node) + && (agg_node_right(it_node) != omit_subtree)) { + if (agg_node_right(it_node)->info) rfapiRibUpdatePendingNode(bgp, rfd, it, - it_node->l_right, lifetime); - rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, it_node->l_right, + agg_node_right(it_node), + lifetime); + rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, + agg_node_right(it_node), omit_subtree, lifetime); } } @@ -1788,13 +1797,13 @@ void rfapiRibUpdatePendingNodeSubtree( */ int rfapiRibFTDFilterRecentPrefix( struct rfapi_descriptor *rfd, - struct route_node *it_rn, /* import table node */ + struct agg_node *it_rn, /* import table node */ struct prefix *pfx_target_original) /* query target */ { struct bgp *bgp = rfd->bgp; afi_t afi = family2afi(it_rn->p.family); time_t prefix_time; - struct route_node *trn; + struct agg_node *trn; /* * Not in FTD mode, so allow prefix @@ -1833,10 +1842,10 @@ int rfapiRibFTDFilterRecentPrefix( /* * check this NVE's timestamp for this prefix */ - trn = route_node_get(rfd->rsp_times[afi], &it_rn->p); /* locks trn */ + trn = agg_node_get(rfd->rsp_times[afi], &it_rn->p); /* locks trn */ prefix_time = (time_t)trn->info; if (trn->lock > 1) - route_unlock_node(trn); + agg_unlock_node(trn); #if DEBUG_FTD_FILTER_RECENT vnc_zlog_debug_verbose("%s: last sent time %lu, last allowed time %lu", @@ -1883,9 +1892,9 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, afi_t afi; struct rfapi_info *ri; int need_insert; - struct route_node *rn; + struct agg_node *rn; int rib_node_started_nonempty = 0; - struct route_node *trn; + struct agg_node *trn; int allowed = 0; /* save in case we delete nhp */ @@ -1947,13 +1956,13 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, /* * Look up prefix in RIB */ - rn = route_node_get(rfd->rib[afi], &pfx); /* locks rn */ + rn = agg_node_get(rfd->rib[afi], &pfx); /* locks rn */ if (rn->info) { rib_node_started_nonempty = 1; } else { rn->info = skiplist_new(0, rfapi_rib_key_cmp, NULL); - route_lock_node(rn); + agg_lock_node(rn); } /* @@ -2063,15 +2072,15 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, rfapiRibStartTimer(rfd, ri, rn, 0); RFAPI_RIB_CHECK_COUNTS(0, 0); - route_unlock_node(rn); + agg_unlock_node(rn); /* * update this NVE's timestamp for this prefix */ - trn = route_node_get(rfd->rsp_times[afi], &pfx); /* locks trn */ + trn = agg_node_get(rfd->rsp_times[afi], &pfx); /* locks trn */ trn->info = (void *)(uintptr_t)bgp_clock(); if (trn->lock > 1) - route_unlock_node(trn); + agg_unlock_node(trn); { char str_pfx[PREFIX_STRLEN]; @@ -2108,7 +2117,7 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, } void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it, - afi_t afi, struct route_node *it_node) + afi_t afi, struct agg_node *it_node) { struct rfapi_descriptor *rfd; struct listnode *node; @@ -2124,7 +2133,7 @@ void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it, * identifies the rfd that owns it. */ struct rfapi_monitor_eth *m; - struct route_node *rn; + struct agg_node *rn; struct skiplist *sl; void *cursor; int rc; @@ -2154,12 +2163,12 @@ void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it, * NVE, it's OK to send an update with the * delete */ - if ((rn = route_node_lookup(m->rfd->rib[afi], - &it_node->p))) { + if ((rn = agg_node_lookup(m->rfd->rib[afi], + &it_node->p))) { rfapiRibUpdatePendingNode( bgp, m->rfd, it, it_node, m->rfd->response_lifetime); - route_unlock_node(rn); + agg_unlock_node(rn); } } } @@ -2177,8 +2186,8 @@ void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it, * this * NVE, it's OK to send an update with the delete */ - if ((rn = route_node_lookup(m->rfd->rib[afi], - &it_node->p))) { + if ((rn = agg_node_lookup(m->rfd->rib[afi], + &it_node->p))) { rfapiRibUpdatePendingNode( bgp, m->rfd, it, it_node, m->rfd->response_lifetime); @@ -2192,7 +2201,7 @@ void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it, for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, rfd)) { - struct route_node *rn; + struct agg_node *rn; vnc_zlog_debug_verbose( "%s: comparing rfd(%p)->import_table=%p to it=%p", @@ -2209,12 +2218,12 @@ void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it, * prefix * previously, we should send an updated response. */ - if ((rn = route_node_lookup(rfd->rib[afi], - &it_node->p))) { + if ((rn = agg_node_lookup(rfd->rib[afi], + &it_node->p))) { rfapiRibUpdatePendingNode( bgp, rfd, it, it_node, rfd->response_lifetime); - route_unlock_node(rn); + agg_unlock_node(rn); } } } @@ -2406,13 +2415,13 @@ void rfapiRibShowResponses(void *stream, struct prefix *pfx_match, for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - struct route_node *rn; + struct agg_node *rn; if (!rfd->rib[afi]) continue; - for (rn = route_top(rfd->rib[afi]); rn; - rn = route_next(rn)) { + for (rn = agg_route_top(rfd->rib[afi]); rn; + rn = agg_route_next(rn)) { struct skiplist *sl; char str_pfx[PREFIX_STRLEN]; diff --git a/bgpd/rfapi/rfapi_rib.h b/bgpd/rfapi/rfapi_rib.h index 0542727c2e..a8872295cd 100644 --- a/bgpd/rfapi/rfapi_rib.h +++ b/bgpd/rfapi/rfapi_rib.h @@ -93,17 +93,17 @@ extern void rfapiRibFree(struct rfapi_descriptor *rfd); extern void rfapiRibUpdatePendingNode(struct bgp *bgp, struct rfapi_descriptor *rfd, struct rfapi_import_table *it, - struct route_node *it_node, + struct agg_node *it_node, uint32_t lifetime); extern void rfapiRibUpdatePendingNodeSubtree(struct bgp *bgp, struct rfapi_descriptor *rfd, struct rfapi_import_table *it, - struct route_node *it_node, - struct route_node *omit_subtree, + struct agg_node *it_node, + struct agg_node *omit_subtree, uint32_t lifetime); -extern int rfapiRibPreloadBi(struct route_node *rfd_rib_node, +extern int rfapiRibPreloadBi(struct agg_node *rfd_rib_node, struct prefix *pfx_vn, struct prefix *pfx_un, uint32_t lifetime, struct bgp_info *bi); @@ -113,7 +113,7 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, extern void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it, afi_t afi, - struct route_node *it_node); + struct agg_node *it_node); extern void rfapiRibShowResponsesSummary(void *stream); @@ -124,7 +124,7 @@ extern void rfapiRibShowResponses(void *stream, struct prefix *pfx_match, extern int rfapiRibFTDFilterRecentPrefix( struct rfapi_descriptor *rfd, - struct route_node *it_rn, /* import table node */ + struct agg_node *it_rn, /* import table node */ struct prefix *pfx_target_original); /* query target */ extern void rfapiFreeRfapiUnOptionChain(struct rfapi_un_option *p); diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index cd12edbccb..b2767da8b2 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -23,7 +23,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/vty.h" #include "lib/memory.h" #include "lib/routemap.h" @@ -742,7 +742,7 @@ static void rfapiDebugPrintMonitorEncap(void *stream, m->bi, HVTYNL); } -void rfapiShowItNode(void *stream, struct route_node *rn) +void rfapiShowItNode(void *stream, struct agg_node *rn) { struct bgp_info *bi; char buf[BUFSIZ]; @@ -766,10 +766,10 @@ void rfapiShowItNode(void *stream, struct route_node *rn) /* doesn't show montors */ } -void rfapiShowImportTable(void *stream, const char *label, - struct route_table *rt, int isvpn) +void rfapiShowImportTable(void *stream, const char *label, struct agg_table *rt, + int isvpn) { - struct route_node *rn; + struct agg_node *rn; char buf[BUFSIZ]; int (*fp)(void *, const char *, ...); @@ -782,7 +782,7 @@ void rfapiShowImportTable(void *stream, const char *label, fp(out, "Import Table [%s]%s", label, HVTYNL); - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) { struct bgp_info *bi; if (rn->p.family == AF_ETHERNET) { @@ -851,7 +851,7 @@ int rfapiShowVncQueries(void *stream, struct prefix *pfx_match) for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { - struct route_node *rn; + struct agg_node *rn; int printedquerier = 0; @@ -868,8 +868,8 @@ int rfapiShowVncQueries(void *stream, struct prefix *pfx_match) * IP Queries */ if (rfd->mon) { - for (rn = route_top(rfd->mon); rn; - rn = route_next(rn)) { + for (rn = agg_route_top(rfd->mon); rn; + rn = agg_route_next(rn)) { struct rfapi_monitor_vpn *m; char buf_remain[BUFSIZ]; char buf_pfx[BUFSIZ]; @@ -1012,7 +1012,7 @@ int rfapiShowVncQueries(void *stream, struct prefix *pfx_match) } static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, - struct route_node *rn, struct bgp_info *bi) + struct agg_node *rn, struct bgp_info *bi) { int (*fp)(void *, const char *, ...); struct vty *vty; @@ -1218,13 +1218,13 @@ static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream, for (afi = AFI_IP; afi < AFI_MAX; ++afi) { - struct route_node *rn; + struct agg_node *rn; if (!it->imported_vpn[afi]) continue; - for (rn = route_top(it->imported_vpn[afi]); rn; - rn = route_next(rn)) { + for (rn = agg_route_top(it->imported_vpn[afi]); rn; + rn = agg_route_next(rn)) { struct bgp_info *bi; int count_only; diff --git a/bgpd/rfapi/rfapi_vty.h b/bgpd/rfapi/rfapi_vty.h index a08183aa46..8b881292ac 100644 --- a/bgpd/rfapi/rfapi_vty.h +++ b/bgpd/rfapi/rfapi_vty.h @@ -124,7 +124,7 @@ extern char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn *m, char *buf, extern const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix *p, char *buf, int bufsize); -extern void rfapiShowItNode(void *stream, struct route_node *rn); +extern void rfapiShowItNode(void *stream, struct agg_node *rn); extern char *rfapiEthAddr2Str(const struct ethaddr *ea, char *buf, int bufsize); diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index 69426670a1..6289175645 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -25,7 +25,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/vty.h" #include "lib/log.h" #include "lib/stream.h" @@ -54,7 +54,7 @@ static void vnc_direct_add_rn_group_rd(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg, - struct route_node *rn, struct attr *attr, + struct agg_node *rn, struct attr *attr, afi_t afi, struct rfapi_descriptor *irfd); @@ -172,7 +172,7 @@ static int getce(struct bgp *bgp, struct attr *attr, struct prefix *pfx_ce) } -void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn, +void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn, struct bgp_info *bi) { struct attr *attr = bi->attr; @@ -327,7 +327,7 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn, /* * "Withdrawing a Route" export process */ -void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn, +void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn, struct bgp_info *bi) { afi_t afi = family2afi(rn->p.family); @@ -404,7 +404,7 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn, static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi) { - struct route_node *rn; + struct agg_node *rn; struct bgp_info *ri; vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); @@ -430,8 +430,8 @@ static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi) /* * Go through entire ce import table and export to BGP unicast. */ - for (rn = route_top(bgp->rfapi->it_ce->imported_vpn[afi]); rn; - rn = route_next(rn)) { + for (rn = agg_route_top(bgp->rfapi->it_ce->imported_vpn[afi]); rn; + rn = agg_route_next(rn)) { if (!rn->info) continue; @@ -513,7 +513,7 @@ static void vnc_direct_bgp_vpn_disable_ce(struct bgp *bgp, afi_t afi) * Export methods that proxy nexthop BEGIN ***********************************************************************/ -static struct ecommunity *vnc_route_origin_ecom(struct route_node *rn) +static struct ecommunity *vnc_route_origin_ecom(struct agg_node *rn) { struct ecommunity *new; struct bgp_info *bi; @@ -586,8 +586,8 @@ static struct ecommunity *vnc_route_origin_ecom_single(struct in_addr *origin) static int encap_attr_export(struct attr *new, struct attr *orig, struct prefix *new_nexthop, - struct route_node *rn) /* for VN addrs for ecom list */ - /* if rn is 0, use route's nexthop */ + struct agg_node *rn) /* for VN addrs for ecom list */ + /* if rn is 0, use route's nexthop */ { struct prefix orig_nexthop; struct prefix *use_nexthop; @@ -692,7 +692,7 @@ encap_attr_export(struct attr *new, struct attr *orig, */ void vnc_direct_bgp_add_prefix(struct bgp *bgp, struct rfapi_import_table *import_table, - struct route_node *rn) + struct agg_node *rn) { struct attr attr = {0}; struct listnode *node, *nnode; @@ -803,7 +803,7 @@ void vnc_direct_bgp_add_prefix(struct bgp *bgp, */ void vnc_direct_bgp_del_prefix(struct bgp *bgp, struct rfapi_import_table *import_table, - struct route_node *rn) + struct agg_node *rn) { struct listnode *node, *nnode; struct rfapi_rfg_name *rfgn; @@ -965,8 +965,8 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) */ if (rfgn->rfg == rfg) { - struct route_table *rt = NULL; - struct route_node *rn; + struct agg_table *rt = NULL; + struct agg_node *rn; struct attr attr = {0}; struct rfapi_import_table *import_table; @@ -987,7 +987,8 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) /* * Walk the NVE-Group's VNC Import table */ - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; + rn = agg_route_next(rn)) { if (rn->info) { @@ -1111,8 +1112,8 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) */ if (rfg && rfgn->rfg == rfg) { - struct route_table *rt = NULL; - struct route_node *rn; + struct agg_table *rt = NULL; + struct agg_node *rn; struct rfapi_import_table *import_table; import_table = rfg->rfapi_import_table; @@ -1128,7 +1129,8 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) /* * Walk the NVE-Group's VNC Import table */ - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; + rn = agg_route_next(rn)) { if (rn->info) { @@ -1159,7 +1161,7 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) static void vnc_direct_add_rn_group_rd(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg, - struct route_node *rn, struct attr *attr, + struct agg_node *rn, struct attr *attr, afi_t afi, struct rfapi_descriptor *irfd) { struct prefix nhp; @@ -1279,8 +1281,8 @@ static void vnc_direct_bgp_add_group_afi(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg, afi_t afi) { - struct route_table *rt = NULL; - struct route_node *rn; + struct agg_table *rt = NULL; + struct agg_node *rn; struct attr attr = {0}; struct rfapi_import_table *import_table; @@ -1311,7 +1313,7 @@ static void vnc_direct_bgp_add_group_afi(struct bgp *bgp, /* * Walk the NVE-Group's VNC Import table */ - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) { if (rn->info) { @@ -1366,7 +1368,7 @@ void vnc_direct_bgp_add_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) static void vnc_direct_del_rn_group_rd(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg, - struct route_node *rn, afi_t afi, + struct agg_node *rn, afi_t afi, struct rfapi_descriptor *irfd) { if (irfd == NULL) @@ -1388,8 +1390,8 @@ static void vnc_direct_bgp_del_group_afi(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg, afi_t afi) { - struct route_table *rt = NULL; - struct route_node *rn; + struct agg_table *rt = NULL; + struct agg_node *rn; struct rfapi_import_table *import_table; vnc_zlog_debug_verbose("%s: entry", __func__); @@ -1412,7 +1414,7 @@ static void vnc_direct_bgp_del_group_afi(struct bgp *bgp, /* * Walk the NVE-Group's VNC Import table */ - for (rn = route_top(rt); rn; rn = route_next(rn)) + for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) if (rn->info) { if (rfg->type == RFAPI_GROUP_CFG_VRF) vnc_direct_del_rn_group_rd(bgp, rfg, rn, afi, @@ -1473,14 +1475,14 @@ void vnc_direct_bgp_reexport_group_afi(struct bgp *bgp, } -static void vnc_direct_bgp_unexport_table(afi_t afi, struct route_table *rt, +static void vnc_direct_bgp_unexport_table(afi_t afi, struct agg_table *rt, struct list *nve_list) { if (nve_list) { - struct route_node *rn; + struct agg_node *rn; - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) { if (rn->info) { diff --git a/bgpd/rfapi/vnc_export_bgp_p.h b/bgpd/rfapi/vnc_export_bgp_p.h index c164a35432..e074c3eaad 100644 --- a/bgpd/rfapi/vnc_export_bgp_p.h +++ b/bgpd/rfapi/vnc_export_bgp_p.h @@ -29,19 +29,19 @@ #include "rfapi_private.h" -extern void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn, +extern void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct agg_node *rn, struct bgp_info *bi); -extern void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn, +extern void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn, struct bgp_info *bi); extern void vnc_direct_bgp_add_prefix(struct bgp *bgp, struct rfapi_import_table *import_table, - struct route_node *rn); + struct agg_node *rn); extern void vnc_direct_bgp_del_prefix(struct bgp *bgp, struct rfapi_import_table *import_table, - struct route_node *rn); + struct agg_node *rn); extern void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd); diff --git a/bgpd/rfapi/vnc_export_table.c b/bgpd/rfapi/vnc_export_table.c index bbdb59c125..5e00a1017b 100644 --- a/bgpd/rfapi/vnc_export_table.c +++ b/bgpd/rfapi/vnc_export_table.c @@ -21,7 +21,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/memory.h" #include "lib/vty.h" @@ -33,11 +33,11 @@ #include "bgpd/rfapi/rfapi_import.h" #include "bgpd/rfapi/vnc_debug.h" -struct route_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type, - struct prefix *p) +struct agg_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type, + struct prefix *p) { - struct route_table *t = NULL; - struct route_node *rn = NULL; + struct agg_table *t = NULL; + struct agg_node *rn = NULL; afi_t afi; if (!bgp || !bgp->rfapi) @@ -49,27 +49,27 @@ struct route_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type, switch (type) { case EXPORT_TYPE_BGP: if (!bgp->rfapi->rt_export_bgp[afi]) - bgp->rfapi->rt_export_bgp[afi] = route_table_init(); + bgp->rfapi->rt_export_bgp[afi] = agg_table_init(); t = bgp->rfapi->rt_export_bgp[afi]; break; case EXPORT_TYPE_ZEBRA: if (!bgp->rfapi->rt_export_zebra[afi]) - bgp->rfapi->rt_export_zebra[afi] = route_table_init(); + bgp->rfapi->rt_export_zebra[afi] = agg_table_init(); t = bgp->rfapi->rt_export_zebra[afi]; break; } if (t) - rn = route_node_get(t, p); + rn = agg_node_get(t, p); return rn; } -struct route_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type, - struct prefix *p) +struct agg_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type, + struct prefix *p) { - struct route_table *t = NULL; - struct route_node *rn = NULL; + struct agg_table *t = NULL; + struct agg_node *rn = NULL; afi_t afi; if (!bgp || !bgp->rfapi) @@ -81,19 +81,19 @@ struct route_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type, switch (type) { case EXPORT_TYPE_BGP: if (!bgp->rfapi->rt_export_bgp[afi]) - bgp->rfapi->rt_export_bgp[afi] = route_table_init(); + bgp->rfapi->rt_export_bgp[afi] = agg_table_init(); t = bgp->rfapi->rt_export_bgp[afi]; break; case EXPORT_TYPE_ZEBRA: if (!bgp->rfapi->rt_export_zebra[afi]) - bgp->rfapi->rt_export_zebra[afi] = route_table_init(); + bgp->rfapi->rt_export_zebra[afi] = agg_table_init(); t = bgp->rfapi->rt_export_zebra[afi]; break; } if (t) - rn = route_node_lookup(t, p); + rn = agg_node_lookup(t, p); return rn; } @@ -101,7 +101,7 @@ struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype, struct prefix *p, struct peer *peer, uint8_t type, uint8_t subtype) { - struct route_node *etn; + struct agg_node *etn; struct vnc_export_info *eti; etn = vnc_etn_get(bgp, etype, p); @@ -116,7 +116,7 @@ struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype, } if (eti) { - route_unlock_node(etn); + agg_unlock_node(etn); } else { eti = XCALLOC(MTYPE_RFAPI_ETI, sizeof(struct vnc_export_info)); assert(eti); @@ -134,7 +134,7 @@ struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype, void vnc_eti_delete(struct vnc_export_info *goner) { - struct route_node *etn; + struct agg_node *etn; struct vnc_export_info *eti; struct vnc_export_info *eti_prev = NULL; @@ -160,7 +160,7 @@ void vnc_eti_delete(struct vnc_export_info *goner) goner->node = NULL; XFREE(MTYPE_RFAPI_ETI, goner); - route_unlock_node(etn); + agg_unlock_node(etn); } struct vnc_export_info *vnc_eti_checktimer(struct bgp *bgp, @@ -168,7 +168,7 @@ struct vnc_export_info *vnc_eti_checktimer(struct bgp *bgp, struct prefix *p, struct peer *peer, uint8_t type, uint8_t subtype) { - struct route_node *etn; + struct agg_node *etn; struct vnc_export_info *eti; etn = vnc_etn_lookup(bgp, etype, p); @@ -183,7 +183,7 @@ struct vnc_export_info *vnc_eti_checktimer(struct bgp *bgp, } } - route_unlock_node(etn); + agg_unlock_node(etn); if (eti && eti->timer) return eti; diff --git a/bgpd/rfapi/vnc_export_table.h b/bgpd/rfapi/vnc_export_table.h index 3ccf8661e7..fdb35e81e1 100644 --- a/bgpd/rfapi/vnc_export_table.h +++ b/bgpd/rfapi/vnc_export_table.h @@ -37,7 +37,7 @@ typedef enum vnc_export_type { struct vnc_export_info { struct vnc_export_info *next; - struct route_node *node; + struct agg_node *node; struct peer *peer; uint8_t type; uint8_t subtype; @@ -45,11 +45,11 @@ struct vnc_export_info { struct thread *timer; }; -extern struct route_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type, - struct prefix *p); +extern struct agg_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type, + struct prefix *p); -extern struct route_node * -vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type, struct prefix *p); +extern struct agg_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type, + struct prefix *p); extern struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype, diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 72363f7cfe..6022e4cc24 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -25,7 +25,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/vty.h" #include "lib/log.h" #include "lib/memory.h" @@ -1737,9 +1737,9 @@ static void vnc_import_bgp_exterior_add_route_it( rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_orig_nexthop); for (it = h->imports; it; it = it->next) { - struct route_table *table; - struct route_node *rn; - struct route_node *par; + struct agg_table *table; + struct agg_node *rn; + struct agg_node *par; struct bgp_info *bi_interior; int have_usable_route; @@ -1753,7 +1753,7 @@ static void vnc_import_bgp_exterior_add_route_it( table = it->imported_vpn[afi]; - for (rn = route_node_match(table, &pfx_orig_nexthop), + for (rn = agg_node_match(table, &pfx_orig_nexthop), have_usable_route = 0; (!have_usable_route) && rn;) { @@ -1821,9 +1821,9 @@ static void vnc_import_bgp_exterior_add_route_it( 0, NULL, (void (*)(void *)) prefix_free); - route_lock_node(rn); /* for skiplist */ + agg_lock_node(rn); /* for skiplist */ } - route_lock_node(rn); /* for skiplist entry */ + agg_lock_node(rn); /* for skiplist entry */ prefix_copy(pfx_mon, prefix); if (!skiplist_insert( RFAPI_MONITOR_EXTERIOR(rn)->source, @@ -1832,14 +1832,14 @@ static void vnc_import_bgp_exterior_add_route_it( bgp_info_lock(info); } } - par = rn->parent; + par = agg_node_parent(rn); if (par) - route_lock_node(par); - route_unlock_node(rn); + agg_lock_node(par); + agg_unlock_node(rn); rn = par; } if (rn) - route_unlock_node(rn); + agg_unlock_node(rn); if (!have_usable_route) { struct prefix *pfx_mon = prefix_new(); @@ -1928,15 +1928,15 @@ void vnc_import_bgp_exterior_del_route( rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_orig_nexthop); for (it = h->imports; it; it = it->next) { - struct route_table *table; - struct route_node *rn; - struct route_node *par; + struct agg_table *table; + struct agg_node *rn; + struct agg_node *par; struct bgp_info *bi_interior; int have_usable_route; table = it->imported_vpn[afi]; - for (rn = route_node_match(table, &pfx_orig_nexthop), + for (rn = agg_node_match(table, &pfx_orig_nexthop), have_usable_route = 0; (!have_usable_route) && rn;) { @@ -1987,9 +1987,9 @@ void vnc_import_bgp_exterior_del_route( info, NULL)) { bgp_info_unlock(info); - route_unlock_node( + agg_unlock_node( rn); /* sl entry - */ + */ } if (skiplist_empty( RFAPI_MONITOR_EXTERIOR( @@ -2002,7 +2002,7 @@ void vnc_import_bgp_exterior_del_route( RFAPI_MONITOR_EXTERIOR( rn) ->source = NULL; - route_unlock_node( + agg_unlock_node( rn); /* skiplist itself */ @@ -2010,14 +2010,14 @@ void vnc_import_bgp_exterior_del_route( } } } - par = rn->parent; + par = agg_node_parent(rn); if (par) - route_lock_node(par); - route_unlock_node(rn); + agg_lock_node(par); + agg_unlock_node(rn); rn = par; } if (rn) - route_unlock_node(rn); + agg_unlock_node(rn); if (!have_usable_route) { if (!skiplist_delete(it->monitor_exterior_orphans, info, @@ -2038,11 +2038,11 @@ void vnc_import_bgp_exterior_del_route( */ void vnc_import_bgp_exterior_add_route_interior( struct bgp *bgp, struct rfapi_import_table *it, - struct route_node *rn_interior, /* VPN IT node */ - struct bgp_info *bi_interior) /* VPN IT route */ + struct agg_node *rn_interior, /* VPN IT node */ + struct bgp_info *bi_interior) /* VPN IT route */ { afi_t afi = family2afi(rn_interior->p.family); - struct route_node *par; + struct agg_node *par; struct bgp_info *bi_exterior; struct prefix *pfx_exterior; /* exterior pfx */ void *cursor; @@ -2161,7 +2161,8 @@ void vnc_import_bgp_exterior_add_route_interior( * Look up the tree for possible pulldown candidates. * Find nearest parent with an exterior route monitor */ - for (par = rn_interior->parent; par; par = par->parent) { + for (par = agg_node_parent(rn_interior); par; + par = agg_node_parent(par)) { if (RFAPI_HAS_MONITOR_EXTERIOR(par)) break; } @@ -2211,13 +2212,13 @@ void vnc_import_bgp_exterior_add_route_interior( ->source = skiplist_new( 0, NULL, (void (*)(void *))prefix_free); - route_lock_node(rn_interior); + agg_lock_node(rn_interior); } skiplist_insert( RFAPI_MONITOR_EXTERIOR(rn_interior) ->source, bi_exterior, pfx_mon); - route_lock_node(rn_interior); + agg_lock_node(rn_interior); /* * Delete constructed exterior routes based on @@ -2291,12 +2292,12 @@ void vnc_import_bgp_exterior_add_route_interior( skiplist_delete(RFAPI_MONITOR_EXTERIOR(par)->source, bi_exterior, NULL); - route_unlock_node(par); /* sl entry */ + agg_unlock_node(par); /* sl entry */ } if (skiplist_empty(RFAPI_MONITOR_EXTERIOR(par)->source)) { skiplist_free(RFAPI_MONITOR_EXTERIOR(par)->source); RFAPI_MONITOR_EXTERIOR(par)->source = NULL; - route_unlock_node(par); /* sl itself */ + agg_unlock_node(par); /* sl itself */ } } @@ -2353,12 +2354,12 @@ void vnc_import_bgp_exterior_add_route_interior( skiplist_new( 0, NULL, (void (*)(void *))prefix_free); - route_lock_node(rn_interior); /* sl */ + agg_lock_node(rn_interior); /* sl */ } skiplist_insert( RFAPI_MONITOR_EXTERIOR(rn_interior)->source, bi_exterior, pfx_mon); - route_lock_node(rn_interior); /* sl entry */ + agg_lock_node(rn_interior); /* sl entry */ if (!list_adopted) { list_adopted = list_new(); } @@ -2397,7 +2398,7 @@ void vnc_import_bgp_exterior_add_route_interior( } if (list_adopted) { struct listnode *node; - struct route_node *bi_exterior; + struct agg_node *bi_exterior; for (ALL_LIST_ELEMENTS_RO(list_adopted, node, bi_exterior)) { skiplist_delete(it->monitor_exterior_orphans, @@ -2419,11 +2420,11 @@ void vnc_import_bgp_exterior_add_route_interior( */ void vnc_import_bgp_exterior_del_route_interior( struct bgp *bgp, struct rfapi_import_table *it, - struct route_node *rn_interior, /* VPN IT node */ - struct bgp_info *bi_interior) /* VPN IT route */ + struct agg_node *rn_interior, /* VPN IT node */ + struct bgp_info *bi_interior) /* VPN IT route */ { afi_t afi = family2afi(rn_interior->p.family); - struct route_node *par; + struct agg_node *par; struct bgp_info *bi_exterior; struct prefix *pfx_exterior; /* exterior pfx */ void *cursor; @@ -2509,7 +2510,8 @@ void vnc_import_bgp_exterior_del_route_interior( * If none is found, par will end up NULL, and we will move * the monitors to the orphan list for this import table */ - for (par = rn_interior->parent; par; par = par->parent) { + for (par = agg_node_parent(rn_interior); par; + par = agg_node_parent(par)) { if (RFAPI_MONITOR_EXTERIOR(par)->valid_interior_count) break; } @@ -2540,11 +2542,11 @@ void vnc_import_bgp_exterior_del_route_interior( skiplist_new( 0, NULL, (void (*)(void *))prefix_free); - route_lock_node(par); /* sl */ + agg_lock_node(par); /* sl */ } skiplist_insert(RFAPI_MONITOR_EXTERIOR(par)->source, bi_exterior, pfx_mon); - route_lock_node(par); /* sl entry */ + agg_lock_node(par); /* sl entry */ /* Add constructed exterior routes based on parent */ for (bi = par->info; bi; bi = bi->next) { @@ -2596,12 +2598,12 @@ void vnc_import_bgp_exterior_del_route_interior( skiplist_delete_first( RFAPI_MONITOR_EXTERIOR(rn_interior)->source); - route_unlock_node(rn_interior); /* sl entry */ + agg_unlock_node(rn_interior); /* sl entry */ } if (skiplist_empty(RFAPI_MONITOR_EXTERIOR(rn_interior)->source)) { skiplist_free(RFAPI_MONITOR_EXTERIOR(rn_interior)->source); RFAPI_MONITOR_EXTERIOR(rn_interior)->source = NULL; - route_unlock_node(rn_interior); /* sl itself */ + agg_unlock_node(rn_interior); /* sl itself */ } } diff --git a/bgpd/rfapi/vnc_import_bgp_p.h b/bgpd/rfapi/vnc_import_bgp_p.h index b38fa2276a..a6fcae926d 100644 --- a/bgpd/rfapi/vnc_import_bgp_p.h +++ b/bgpd/rfapi/vnc_import_bgp_p.h @@ -29,13 +29,13 @@ extern void vnc_import_bgp_exterior_add_route_interior( struct bgp *bgp, struct rfapi_import_table *it, - struct route_node *rn_interior, /* VPN IT node */ - struct bgp_info *bi_interior); /* VPN IT route */ + struct agg_node *rn_interior, /* VPN IT node */ + struct bgp_info *bi_interior); /* VPN IT route */ extern void vnc_import_bgp_exterior_del_route_interior( struct bgp *bgp, struct rfapi_import_table *it, - struct route_node *rn_interior, /* VPN IT node */ - struct bgp_info *bi_interior); /* VPN IT route */ + struct agg_node *rn_interior, /* VPN IT node */ + struct bgp_info *bi_interior); /* VPN IT route */ extern void vnc_import_bgp_exterior_redist_enable_it(struct bgp *bgp, afi_t afi, diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index a2871188e6..a93fb60735 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -25,7 +25,7 @@ #include "lib/zebra.h" #include "lib/prefix.h" -#include "lib/table.h" +#include "lib/agg_table.h" #include "lib/log.h" #include "lib/command.h" #include "lib/zclient.h" @@ -556,7 +556,7 @@ static void import_table_to_nve_list_zebra(struct bgp *bgp, static void vnc_zebra_add_del_prefix(struct bgp *bgp, struct rfapi_import_table *import_table, - struct route_node *rn, + struct agg_node *rn, int add) /* !0 = add, 0 = del */ { struct list *nves; @@ -611,14 +611,14 @@ static void vnc_zebra_add_del_prefix(struct bgp *bgp, void vnc_zebra_add_prefix(struct bgp *bgp, struct rfapi_import_table *import_table, - struct route_node *rn) + struct agg_node *rn) { vnc_zebra_add_del_prefix(bgp, import_table, rn, 1); } void vnc_zebra_del_prefix(struct bgp *bgp, struct rfapi_import_table *import_table, - struct route_node *rn) + struct agg_node *rn) { vnc_zebra_add_del_prefix(bgp, import_table, rn, 0); } @@ -678,8 +678,8 @@ static void vnc_zebra_add_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd, */ if (rfgn->rfg == rfg) { - struct route_table *rt = NULL; - struct route_node *rn; + struct agg_table *rt = NULL; + struct agg_node *rn; struct rfapi_import_table *import_table; import_table = rfg->rfapi_import_table; @@ -692,7 +692,8 @@ static void vnc_zebra_add_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd, /* * Walk the NVE-Group's VNC Import table */ - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; + rn = agg_route_next(rn)) { if (rn->info) { @@ -721,8 +722,8 @@ static void vnc_zebra_add_del_group_afi(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg, afi_t afi, int add) { - struct route_table *rt = NULL; - struct route_node *rn; + struct agg_table *rt = NULL; + struct agg_node *rn; struct rfapi_import_table *import_table; uint8_t family = afi2family(afi); @@ -773,7 +774,8 @@ static void vnc_zebra_add_del_group_afi(struct bgp *bgp, /* * Walk the NVE-Group's VNC Import table */ - for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (rn = agg_route_top(rt); rn; + rn = agg_route_next(rn)) { if (rn->info) { vnc_zebra_route_msg(&rn->p, nexthop_count, diff --git a/bgpd/rfapi/vnc_zebra.h b/bgpd/rfapi/vnc_zebra.h index 708aaeef50..b8c1cb15c4 100644 --- a/bgpd/rfapi/vnc_zebra.h +++ b/bgpd/rfapi/vnc_zebra.h @@ -29,11 +29,11 @@ extern void vnc_zebra_add_prefix(struct bgp *bgp, struct rfapi_import_table *import_table, - struct route_node *rn); + struct agg_node *rn); extern void vnc_zebra_del_prefix(struct bgp *bgp, struct rfapi_import_table *import_table, - struct route_node *rn); + struct agg_node *rn); extern void vnc_zebra_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd); diff --git a/bgpd/rfp-example/librfp/rfp_example.c b/bgpd/rfp-example/librfp/rfp_example.c index cde2d7b352..75e57a029e 100644 --- a/bgpd/rfp-example/librfp/rfp_example.c +++ b/bgpd/rfp-example/librfp/rfp_example.c @@ -55,6 +55,54 @@ DEFUN (rfp_example_config_value, return CMD_SUCCESS; } +DEFUN (rfp_holddown_factor, + rfp_holddown_factor_cmd, + "rfp holddown-factor (0-4294967295)", + RFP_SHOW_STR + "Set Hold-Down Factor as a percentage of registration lifetime.\n" + "Percentage of registration lifetime\n") +{ + struct rfp_instance_t *rfi; + uint32_t value = 0; + + value = strtoul((argv[--argc]->arg), NULL, 10); + rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */ + if (!rfi) { + vty_out(vty, "VNC not configured\n"); + return CMD_WARNING; + } + rfi->rfapi_config.holddown_factor = value; + rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config); + return CMD_SUCCESS; +} + + +DEFUN (rfp_full_table_download, + rfp_full_table_download_cmd, + "rfp full-table-download <on|off>", + RFP_SHOW_STR + "RFP full table download support (default=on)\n" + "Enable RFP full table download\n" + "Disable RFP full table download\n") +{ + struct rfp_instance_t *rfi; + rfapi_rfp_download_type old; + + rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */ + if (!rfi) { + vty_out(vty, "VNC not configured\n"); + return CMD_WARNING; + } + old = rfi->rfapi_config.download_type; + if (argv[--argc]->arg[1] == 'n' || argv[argc]->arg[1] == 'N') + rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_FULL; + else + rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL; + if (old != rfi->rfapi_config.download_type) + rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config); + return CMD_SUCCESS; +} + static void rfp_vty_install() { static int installed = 0; @@ -63,6 +111,8 @@ static void rfp_vty_install() installed = 1; /* example of new cli command */ install_element(BGP_NODE, &rfp_example_config_value_cmd); + install_element(BGP_NODE, &rfp_holddown_factor_cmd); + install_element(BGP_NODE, &rfp_full_table_download_cmd); } /*********************************************************************** @@ -196,7 +246,15 @@ static int rfp_cfg_write_cb(struct vty *vty, void *rfp_start_val) vty_out(vty, "\n"); write++; } - + if (rfi->rfapi_config.holddown_factor != 0) { + vty_out(vty, " rfp holddown-factor %u\n", + rfi->rfapi_config.holddown_factor); + write++; + } + if (rfi->rfapi_config.download_type != RFAPI_RFP_DOWNLOAD_FULL) { + vty_out(vty, " rfp full-table-download off\n"); + write++; + } return write; } @@ -230,7 +288,7 @@ void *rfp_start(struct thread_master *master, struct rfapi_rfp_cfg **cfgp, /* initilize struct rfapi_rfp_cfg, see rfapi.h */ global_rfi.rfapi_config.download_type = - RFAPI_RFP_DOWNLOAD_FULL; /* default=partial */ + RFAPI_RFP_DOWNLOAD_PARTIAL; /* default=partial */ global_rfi.rfapi_config.ftd_advertisement_interval = RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL; global_rfi.rfapi_config.holddown_factor = @@ -2,8 +2,8 @@ # Automake fragment intended to be shared by Makefile.am files in the # tree. When used, should be included at the very top of the file. # -AM_CPPFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@ @WERROR@ -AM_CFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@ @WERROR@ +AM_CPPFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@ +AM_CFLAGS = @ASAN_FLAGS@ @TSAN_FLAGS@ @MSAN_FLAGS@ $(WERROR) AM_V_CLIPPY = $(am__v_CLIPPY_$(V)) am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY)) diff --git a/configure.ac b/configure.ac index fda7e44f00..09a6f364fb 100755 --- a/configure.ac +++ b/configure.ac @@ -132,25 +132,29 @@ dnl - specifically, options to control warnings AC_USE_SYSTEM_EXTENSIONS AC_DEFUN([AC_C_FLAG], [{ + m4_pushdef([cachename],[m4_translit([frr_cv_$1],[ =-],[___])]) + AC_CACHE_CHECK([[whether $CC supports $1]], cachename, [ AC_LANG_PUSH(C) ac_c_flag_save="$CFLAGS" CFLAGS="$CFLAGS $1" - AC_MSG_CHECKING([[whether $CC supports $1]]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[]])], [ - AC_MSG_RESULT([yes]) - m4_if([$3], [], [], [ - CFLAGS="$ac_c_flag_save" - $3 - ]) + cachename=yes ], [ - CFLAGS="$ac_c_flag_save" - AC_MSG_RESULT([no]) - $2 + cachename=no ]) + CFLAGS="$ac_c_flag_save" AC_LANG_POP(C) - }]) + ]) + if test "${cachename}" = yes; then + m4_if([$3], [], [CFLAGS="$CFLAGS $1"], [$3]) + else + : + $2 + fi + m4_popdef([cachename]) +}]) AC_DEFUN([AC_LINK_IFELSE_FLAGS], [{ AC_LANG_PUSH(C) @@ -343,6 +347,8 @@ AC_ARG_ENABLE(vtysh, AS_HELP_STRING([--disable-vtysh], [do not build integrated vty shell for FRR])) AC_ARG_ENABLE(doc, AS_HELP_STRING([--disable-doc], [do not build docs])) +AC_ARG_ENABLE(doc-html, + AS_HELP_STRING([--enable-doc-html], [build HTML docs])) AC_ARG_ENABLE(zebra, AS_HELP_STRING([--disable-zebra], [do not build zebra daemon])) AC_ARG_ENABLE(bgpd, @@ -525,25 +531,10 @@ AM_CONDITIONAL([FPM], [test "x$enable_fpm" = "xyes"]) # # Python for clippy # -AS_IF([test "$host" = "$build"], [ - PYTHONCONFIG="" - # ordering: - # 1. try python3, but respect the user's preference on which minor ver - # 2. try python, which might be py3 or py2 again on the user's preference - # 3. try python2 (can really only be 2.7 but eh) - # 4. try 3.5 > 3.4 > 3.3 > 3.2 > 2.7 through pkg-config (no user pref) - # - # (AX_PYTHON_DEVEL has no clue about py3 vs py2) - # (AX_PYTHON does not do what we need) - - AC_CHECK_TOOLS([PYTHONCONFIG], [python3-config python-config python2-config]) - if test -n "$PYTHONCONFIG"; then - PYTHON_CFLAGS="`\"${PYTHONCONFIG}\" --includes`" - PYTHON_LIBS="`\"${PYTHONCONFIG}\" --libs`" - - AC_MSG_CHECKING([whether we found a working Python version]) - AC_LINK_IFELSE_FLAGS([$PYTHON_CFLAGS], [$PYTHON_LIBS], [AC_LANG_PROGRAM([ +AC_DEFUN([FRR_PYTHON_CHECK_WORKING], [ + AC_MSG_CHECKING([whether we found a working Python version]) + AC_LINK_IFELSE_FLAGS([$PYTHON_CFLAGS], [$PYTHON_LIBS], [AC_LANG_PROGRAM([ #include <Python.h> #if PY_VERSION_HEX < 0x02070000 #error python too old @@ -556,23 +547,8 @@ int main(void); return 0; } ])], [ - PYTHONCONFIG="" - unset PYTHON_LIBS - unset PYTHON_CFLAGS - ]) - fi - - if test -z "$PYTHONCONFIG"; then - PKG_CHECK_MODULES([PYTHON], python-3.5, [], [ - PKG_CHECK_MODULES([PYTHON], python-3.4, [], [ - PKG_CHECK_MODULES([PYTHON], python-3.3, [], [ - PKG_CHECK_MODULES([PYTHON], python-3.2, [], [ - PKG_CHECK_MODULES([PYTHON], python-2.7, [], [ - AC_MSG_FAILURE([could not find python-config or pkg-config python, please install Python development files from libpython-dev or similar]) - ])])])])]) - - - AC_MSG_CHECKING([whether we found a working Python version]) + # some python installs are missing the zlib dependency... + PYTHON_LIBS="${PYTHON_LIBS} -lz" AC_LINK_IFELSE_FLAGS([$PYTHON_CFLAGS], [$PYTHON_LIBS], [AC_LANG_PROGRAM([ #include <Python.h> #if PY_VERSION_HEX < 0x02070000 @@ -586,6 +562,56 @@ int main(void); return 0; } ])], [ + m4_if([$1], [], [ + PYTHONCONFIG="" + unset PYTHON_LIBS + unset PYTHON_CFLAGS + ], [$1]) + ]) + ]) +]) + +AS_IF([test "$host" = "$build"], [ + PYTHONCONFIG="" + + # ordering: + # 1. try python3, but respect the user's preference on which minor ver + # 2. try python, which might be py3 or py2 again on the user's preference + # 3. try python2 (can really only be 2.7 but eh) + # 4. try 3.6 > 3.5 > 3.4 > 3.3 > 3.2 > 2.7 through pkg-config (no user pref) + # + # (AX_PYTHON_DEVEL has no clue about py3 vs py2) + # (AX_PYTHON does not do what we need) + + AC_CHECK_TOOLS([PYTHONCONFIG], [ \ + python3-config \ + python-config \ + python2-config \ + python3.6-config \ + python3.5-config \ + python3.4-config \ + python3.3-config \ + python3.2-config \ + python2.7-config ]) + if test -n "$PYTHONCONFIG"; then + PYTHON_CFLAGS="`\"${PYTHONCONFIG}\" --includes`" + PYTHON_LIBS="`\"${PYTHONCONFIG}\" --ldflags`" + + FRR_PYTHON_CHECK_WORKING([]) + fi + + if test -z "$PYTHONCONFIG"; then + PKG_CHECK_MODULES([PYTHON], python-3.6, [], [ + PKG_CHECK_MODULES([PYTHON], python-3.5, [], [ + PKG_CHECK_MODULES([PYTHON], python-3.4, [], [ + PKG_CHECK_MODULES([PYTHON], python-3.3, [], [ + PKG_CHECK_MODULES([PYTHON], python-3.2, [], [ + PKG_CHECK_MODULES([PYTHON], python-2.7, [], [ + AC_MSG_FAILURE([could not find python-config or pkg-config python, please install Python development files from libpython-dev or similar]) + ])])])])])]) + + + FRR_PYTHON_CHECK_WORKING([ AC_MSG_FAILURE([could not find python-config or pkg-config python, please install Python development files from libpython-dev or similar]) ]) fi @@ -1313,12 +1339,9 @@ FRR_INCLUDES ])dnl dnl disable doc check -if test "${enable_doc}" = "no";then - DOC="" -else - AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [no]) - DOC="doc" -fi +AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build sphinx-build3 sphinx-build2], [no]) +AM_CONDITIONAL(DOC, test "${enable_doc}" != "no") +AM_CONDITIONAL(DOC_HTML, test "${enable_doc_html}" = "yes") dnl -------------------- dnl Daemon disable check @@ -1434,7 +1457,6 @@ fi # set AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno]) -AC_SUBST(DOC) AC_SUBST(RFPTEST) AC_SUBST(LIBRFP) AC_SUBST(RFPINC) @@ -1518,8 +1540,8 @@ AC_SEARCH_LIBS(dlopen, [dl dld], [], [ AC_CHECK_HEADERS([link.h]) -AC_MSG_CHECKING([for dlinfo(RTLD_DI_ORIGIN)]) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +AC_CACHE_CHECK([for dlinfo(RTLD_DI_ORIGIN)], [frr_cv_rtld_di_origin], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdlib.h> #ifdef HAVE_LINK_H #include <link.h> @@ -1529,14 +1551,17 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ char origin[1]; dlinfo (NULL, RTLD_DI_ORIGIN, &origin); ]])], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_DLINFO_ORIGIN, 1, [Have dlinfo RTLD_DI_ORIGIN]) -], [ - AC_MSG_RESULT(no) + frr_cv_rtld_di_origin=yes + ], [ + frr_cv_rtld_di_origin=no + ]) ]) +if test "$frr_cv_rtld_di_origin" = yes; then + AC_DEFINE(HAVE_DLINFO_ORIGIN, 1, [Have dlinfo RTLD_DI_ORIGIN]) +fi -AC_MSG_CHECKING([for dlinfo(RTLD_DI_LINKMAP)]) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +AC_CACHE_CHECK([for dlinfo(RTLD_DI_LINKMAP)], [frr_cv_rtld_di_linkmap], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdlib.h> #ifdef HAVE_LINK_H #include <link.h> @@ -1546,12 +1571,14 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ struct link_map *lm = NULL; dlinfo (NULL, RTLD_DI_LINKMAP, &lm); ]])], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_DLINFO_LINKMAP, 1, [Have dlinfo RTLD_DI_LINKMAP]) -], [ - AC_MSG_RESULT(no) + frr_cv_rtld_di_linkmap=yes + ], [ + frr_cv_rtld_di_linkmap=no + ]) ]) - +if test "$frr_cv_rtld_di_linkmap" = yes; then + AC_DEFINE(HAVE_DLINFO_LINKMAP, 1, [Have dlinfo RTLD_DI_LINKMAP]) +fi AM_CONDITIONAL(SNMP, test "x$SNMP_METHOD" = "xagentx") @@ -1808,8 +1835,8 @@ dnl mallinfo, e.g. such as Umem on Solaris. dnl ----------------------------------------- AC_CHECK_HEADERS([malloc.h malloc/malloc.h],,, [FRR_INCLUDES]) -AC_MSG_CHECKING(whether mallinfo is available) -AC_LINK_IFELSE([AC_LANG_PROGRAM([FRR_INCLUDES [ +AC_CACHE_CHECK([whether mallinfo is available], [frr_cv_mallinfo], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([FRR_INCLUDES [ #ifdef HAVE_MALLOC_H #include <malloc.h> #endif @@ -1819,11 +1846,14 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([FRR_INCLUDES [ ]], [[ struct mallinfo ac_x; ac_x = mallinfo (); ]])], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_MALLINFO,,mallinfo) -], [ - AC_MSG_RESULT(no) + frr_cv_mallinfo=yes + ], [ + frr_cv_mallinfo=no + ]) ]) +if test "$frr_cv_mallinfo" = yes; then + AC_DEFINE(HAVE_MALLINFO,,mallinfo) +fi AC_MSG_CHECKING(whether malloc_usable_size is available) AC_LINK_IFELSE([AC_LANG_PROGRAM([FRR_INCLUDES [ @@ -1983,18 +2013,16 @@ AC_CACHE_VAL(ac_cv_htonl_works, ) AC_MSG_RESULT($ac_cv_htonl_works) -AC_CONFIG_FILES([Makefile +AC_CONFIG_FILES([Makefile],[sed -e 's/^#AUTODERP# //' -i Makefile]) + +AC_CONFIG_FILES([ bgpd/Makefile vtysh/Makefile - doc/Makefile - doc/user/Makefile - doc/manpages/Makefile - doc/developer/Makefile tests/Makefile bgpd/rfp-example/rfptest/Makefile bgpd/rfp-example/librfp/Makefile redhat/frr.spec - debianpkg/Makefile + solaris/Makefile debianpkg/changelog alpine/APKBUILD snapcraft/snapcraft.yaml @@ -2010,8 +2038,6 @@ if test "${enable_bgp_vnc}" != "no"; then fi fi -AC_CONFIG_FILES([solaris/Makefile]) - AC_CONFIG_FILES([vtysh/extract.pl],[chmod +x vtysh/extract.pl]) AC_CONFIG_COMMANDS([lib/route_types.h], [ diff --git a/debianpkg/Makefile.am b/debianpkg/Makefile.am deleted file mode 100644 index e7ae4bb58d..0000000000 --- a/debianpkg/Makefile.am +++ /dev/null @@ -1,47 +0,0 @@ - -EXTRA_DIST = README.Debian README.Maintainer \ - changelog compat control copyright \ - rules source/format tests/control \ - tests/daemons watchfrr.rc \ - backports/README backports/rules \ - backports/debian8/debian/source/format \ - backports/debian8/exclude \ - backports/debian8/versionext \ - backports/debian9/debian/source/format \ - backports/debian9/exclude \ - backports/debian9/versionext \ - backports/ubuntu12.04/debian/control \ - backports/ubuntu12.04/debian/frr.install \ - backports/ubuntu12.04/debian/frr.postinst \ - backports/ubuntu12.04/debian/frr.postrm \ - backports/ubuntu12.04/debian/rules \ - backports/ubuntu12.04/debian/source/format \ - backports/ubuntu12.04/exclude \ - backports/ubuntu12.04/versionext \ - backports/ubuntu14.04/debian/control \ - backports/ubuntu14.04/debian/frr.install \ - backports/ubuntu14.04/debian/frr.postinst \ - backports/ubuntu14.04/debian/frr.postrm \ - backports/ubuntu14.04/debian/rules \ - backports/ubuntu14.04/debian/source/format \ - backports/ubuntu14.04/exclude \ - backports/ubuntu14.04/versionext \ - backports/ubuntu16.04/debian/source/format \ - backports/ubuntu16.04/exclude \ - backports/ubuntu16.04/versionext \ - backports/ubuntu17.10/debian/control \ - backports/ubuntu17.10/debian/source/format \ - backports/ubuntu17.10/exclude \ - backports/ubuntu17.10/versionext \ - backports/ubuntu18.04/debian/control \ - backports/ubuntu18.04/debian/source/format \ - backports/ubuntu18.04/exclude \ - backports/ubuntu18.04/versionext \ - frr-doc.docs frr-doc.info frr-doc.install \ - frr-doc.lintian-overrides frr.conf \ - frr-dbg.lintian-overrides \ - frr.dirs frr.docs frr.install \ - frr.lintian-overrides frr.logrotate \ - frr.manpages frr.pam frr.postinst frr.postrm \ - frr.preinst frr.prerm \ - frr-pythontools.install diff --git a/debianpkg/subdir.am b/debianpkg/subdir.am new file mode 100644 index 0000000000..b6251962b7 --- /dev/null +++ b/debianpkg/subdir.am @@ -0,0 +1,72 @@ +# +# debianpkg +# + +EXTRA_DIST += \ + debianpkg/README.Debian \ + debianpkg/README.Maintainer \ + debianpkg/changelog \ + debianpkg/compat \ + debianpkg/control \ + debianpkg/copyright \ + debianpkg/rules \ + debianpkg/source/format \ + debianpkg/tests/control \ + debianpkg/tests/daemons \ + debianpkg/watchfrr.rc \ + \ + debianpkg/backports/README \ + debianpkg/backports/rules \ + debianpkg/backports/debian8/debian/source/format \ + debianpkg/backports/debian8/exclude \ + debianpkg/backports/debian8/versionext \ + debianpkg/backports/debian9/debian/source/format \ + debianpkg/backports/debian9/exclude \ + debianpkg/backports/debian9/versionext \ + debianpkg/backports/ubuntu12.04/debian/control \ + debianpkg/backports/ubuntu12.04/debian/frr.install \ + debianpkg/backports/ubuntu12.04/debian/frr.postinst \ + debianpkg/backports/ubuntu12.04/debian/frr.postrm \ + debianpkg/backports/ubuntu12.04/debian/rules \ + debianpkg/backports/ubuntu12.04/debian/source/format \ + debianpkg/backports/ubuntu12.04/exclude \ + debianpkg/backports/ubuntu12.04/versionext \ + debianpkg/backports/ubuntu14.04/debian/control \ + debianpkg/backports/ubuntu14.04/debian/frr.install \ + debianpkg/backports/ubuntu14.04/debian/frr.postinst \ + debianpkg/backports/ubuntu14.04/debian/frr.postrm \ + debianpkg/backports/ubuntu14.04/debian/rules \ + debianpkg/backports/ubuntu14.04/debian/source/format \ + debianpkg/backports/ubuntu14.04/exclude \ + debianpkg/backports/ubuntu14.04/versionext \ + debianpkg/backports/ubuntu16.04/debian/source/format \ + debianpkg/backports/ubuntu16.04/exclude \ + debianpkg/backports/ubuntu16.04/versionext \ + debianpkg/backports/ubuntu17.10/debian/control \ + debianpkg/backports/ubuntu17.10/debian/source/format \ + debianpkg/backports/ubuntu17.10/exclude \ + debianpkg/backports/ubuntu17.10/versionext \ + debianpkg/backports/ubuntu18.04/debian/control \ + debianpkg/backports/ubuntu18.04/debian/source/format \ + debianpkg/backports/ubuntu18.04/exclude \ + debianpkg/backports/ubuntu18.04/versionext \ + \ + debianpkg/frr-dbg.lintian-overrides \ + debianpkg/frr-doc.docs \ + debianpkg/frr-doc.info \ + debianpkg/frr-doc.install \ + debianpkg/frr-doc.lintian-overrides \ + debianpkg/frr-pythontools.install \ + debianpkg/frr.conf \ + debianpkg/frr.dirs \ + debianpkg/frr.docs \ + debianpkg/frr.install \ + debianpkg/frr.lintian-overrides \ + debianpkg/frr.logrotate \ + debianpkg/frr.manpages \ + debianpkg/frr.pam \ + debianpkg/frr.postinst \ + debianpkg/frr.postrm \ + debianpkg/frr.preinst \ + debianpkg/frr.prerm \ + # end diff --git a/doc/.gitignore b/doc/.gitignore index e539d9a97b..d99a6a5b2d 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,5 +1,4 @@ -Makefile -Makefile.in +!Makefile mdate-sh draft-zebra-00.txt *.pdf diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000000..3b4d3d24ab --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,18 @@ +all: ALWAYS + @$(MAKE) -s -C .. doc +%: ALWAYS + @$(MAKE) -s -C .. doc/$@ +html: + @$(MAKE) -s -C .. doc/user/_build/html/.buildinfo +info: + @$(MAKE) -s -C .. doc/user/_build/texinfo/frr.info +pdf: + @$(MAKE) -s -C .. doc/user/_build/latexpdf +frr.info: info +frr.pdf: pdf + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles html info frr.info pdf frr.pdf +.SUFFIXES: diff --git a/doc/Makefile.am b/doc/Makefile.am deleted file mode 100644 index a2f2f19414..0000000000 --- a/doc/Makefile.am +++ /dev/null @@ -1,293 +0,0 @@ -## Process this file with automake to produce Makefile.in. - -# Pass down make invocation to each subdirectory. -# -# Each of these directories contains a Sphinx-generated Makefile that has been -# modified to implement all the targets required by Automake, as documented in -# the 'Third-Party Makefiles' section of the Automake docs. -# -# Note the absence of the 'developer' directory here; development docs are -# never built as part of a regular build. They are only built when explicitly -# asked for. See comment further down. - -# Sphinx is not designed to be invoked multiple times against the same toctree. -.NOTPARALLEL: - -SUBDIRS = manpages user -AM_MAKEFLAGS = DESTDIR=${DESTDIR} infodir=${infodir} - -MANPAGE_BUILDDIR = manpages/_build/man - -# This is a hack, see comment further down. -man_MANS = $(MANPAGE_BUILDDIR)/frr.1 - -if PIMD -man_MANS += $(MANPAGE_BUILDDIR)/pimd.8 -man_MANS += $(MANPAGE_BUILDDIR)/mtracebis.8 -endif - -if PBRD -man_MANS += $(MANPAGE_BUILDDIR)/pbrd.8 -endif - -if BGPD -man_MANS += $(MANPAGE_BUILDDIR)/bgpd.8 -endif - -if ISISD -man_MANS += $(MANPAGE_BUILDDIR)/isisd.8 -endif - -if OSPF6D -man_MANS += $(MANPAGE_BUILDDIR)/ospf6d.8 -endif - -if OSPFCLIENT -man_MANS += $(MANPAGE_BUILDDIR)/ospfclient.8 -endif - -if OSPFD -man_MANS += $(MANPAGE_BUILDDIR)/ospfd.8 -endif - -if LDPD -man_MANS += $(MANPAGE_BUILDDIR)/ldpd.8 -endif - -if RIPD -man_MANS += $(MANPAGE_BUILDDIR)/ripd.8 -endif - -if RIPNGD -man_MANS += $(MANPAGE_BUILDDIR)/ripngd.8 -endif - -if NHRPD -man_MANS += $(MANPAGE_BUILDDIR)/nhrpd.8 -endif - -if VTYSH -man_MANS += $(MANPAGE_BUILDDIR)/vtysh.1 -endif - -if WATCHFRR -man_MANS += $(MANPAGE_BUILDDIR)/watchfrr.8 -endif - -if ZEBRA -man_MANS += $(MANPAGE_BUILDDIR)/zebra.8 -endif - -if EIGRPD -man_MANS += $(MANPAGE_BUILDDIR)/eigrpd.8 -endif - -if SHARPD -man_MANS += $(MANPAGE_BUILDDIR)/sharpd.8 -endif - -if STATICD -man_MANS += $(MANPAGE_BUILDDIR)/staticd.8 -endif - -if BFDD -man_MANS += $(MANPAGE_BUILDDIR)/bfdd.8 -endif - -# Automake is particular about manpages. It is aware of them and has some -# special facilities for handling them, but it assumes that manpages are always -# given in groff source and so these facilities are limited to simply -# specifying the path to the groff sources in a special variable. There is no -# target for building manpages that can be extended, as there are for pdf, -# html, dvi, etc. Unfortunately this leaves us with hijacking the -# 'install-data' and 'all' targets in the 3rd-party Makefile in manpages/ to -# make sure manpages are always built, and then using the special Automake -# variable defined above in order to take advantage of automatic installation. -# -# However, it is conceivable that someone may want to build just the manpages, -# so here's an explicit target for that. -man: - $(MAKE) -C manpages man - -# Automake automatically defines targets for various document formats. All of -# the child 3rd-party Makefiles are aware of all Automake targets and implement -# the ones we are interested in. -# -# The SUBDIRS variable at the top of this Makefile.am causes the following -# implicit Automake targets to only build user documentation, and not developer -# documentation: -# - info -# - html -# - pdf -# -# If you wish to build developer documentation, use these targets: -developer-info: - $(MAKE) -C developer info - -developer-pdf: - $(MAKE) -C developer latexpdf - -developer-html: - $(MAKE) -C developer html - -# If you want to build the developer's docs in other formats, try the -# following: -# -# $ cd developer -# $ make help - -# dist tarballs want doc sources -EXTRA_DIST = frr-sphinx.mk \ - manpages/bgpd.rst \ - manpages/common-options.rst \ - manpages/conf.py \ - manpages/defines.rst \ - manpages/eigrpd.rst \ - manpages/epilogue.rst \ - manpages/frr.rst \ - manpages/index.rst \ - manpages/isisd.rst \ - manpages/ldpd.rst \ - manpages/Makefile.am \ - manpages/mtracebis.rst \ - manpages/nhrpd.rst \ - manpages/ospf6d.rst \ - manpages/ospfclient.rst \ - manpages/ospfd.rst \ - manpages/pimd.rst \ - manpages/ripd.rst \ - manpages/pbrd.rst \ - manpages/ripngd.rst \ - manpages/sharpd.rst \ - manpages/staticd.rst \ - manpages/vtysh.rst \ - manpages/watchfrr.rst \ - manpages/zebra.rst \ - manpages/bfdd.rst \ - manpages/bfd-options.rst \ - developer/bgpd.rst \ - developer/bgp-typecodes.rst \ - developer/building-frr-for-openwrt.rst \ - developer/building-frr-on-alpine.rst \ - developer/building-frr-on-centos6.rst \ - developer/building-frr-on-centos7.rst \ - developer/building-frr-on-debian8.rst \ - developer/building-frr-on-debian9.rst \ - developer/building-frr-on-fedora24.rst \ - developer/building-frr-on-freebsd10.rst \ - developer/building-frr-on-freebsd11.rst \ - developer/building-frr-on-freebsd9.rst \ - developer/building-frr-on-netbsd6.rst \ - developer/building-frr-on-netbsd7.rst \ - developer/building-frr-on-omnios.rst \ - developer/building-frr-on-openbsd6.rst \ - developer/building-frr-on-ubuntu1204.rst \ - developer/building-frr-on-ubuntu1404.rst \ - developer/building-frr-on-ubuntu1604.rst \ - developer/building-frr-on-ubuntu1804.rst \ - developer/building.rst \ - developer/cli.rst \ - developer/conf.py \ - developer/draft-zebra-00.ms \ - developer/hooks.rst \ - developer/index.rst \ - developer/ldpd-basic-test-setup.md \ - developer/library.rst \ - developer/logging.rst \ - developer/Makefile.in \ - developer/maintainer-release-build.rst \ - developer/memtypes.rst \ - developer/modules.rst \ - developer/next-hop-tracking.rst \ - developer/ospf-api.rst \ - developer/ospf.rst \ - developer/ospf-sr.rst \ - developer/workflow.rst \ - developer/zebra.rst \ - user/babeld.rst \ - user/ldpd.rst \ - user/basic.rst \ - user/bgp.rst \ - user/bugs.rst \ - user/conf.py \ - user/eigrpd.rst \ - user/filter.rst \ - user/glossary.rst \ - user/index.rst \ - user/installation.rst \ - user/ipv6.rst \ - user/isisd.rst \ - user/kernel.rst \ - user/Makefile.am \ - user/nhrpd.rst \ - user/ospf6d.rst \ - user/ospfd.rst \ - user/ospf_fundamentals.rst \ - user/overview.rst \ - user/packet-dumps.rst \ - user/pim.rst \ - user/ripd.rst \ - user/pbr.rst \ - user/ripngd.rst \ - user/routemap.rst \ - user/routeserver.rst \ - user/rpki.rst \ - user/setup.rst \ - user/sharp.rst \ - user/snmp.rst \ - user/snmptrap.rst \ - user/static.rst \ - user/Useful_Sysctl_Settings.md \ - user/vnc.rst \ - user/vtysh.rst \ - user/zebra.rst \ - user/bfd.rst \ - user/flowspec.rst \ - mpls/ChangeLog.opaque.txt \ - mpls/ospfd.conf \ - mpls/cli_summary.txt \ - mpls/opaque_lsa.txt \ - figures/cligraph.png \ - figures/cligraph.svg \ - figures/fig-normal-processing.dia \ - figures/fig-normal-processing.png \ - figures/fig-normal-processing.txt \ - figures/fig-rs-processing.dia \ - figures/fig-rs-processing.png \ - figures/fig-rs-processing.txt \ - figures/fig_topologies_full.dia \ - figures/fig_topologies_full.png \ - figures/fig_topologies_full.txt \ - figures/fig_topologies_rs.dia \ - figures/fig_topologies_rs.png \ - figures/fig_topologies_rs.txt \ - figures/fig-vnc-commercial-route-reflector.dia \ - figures/fig-vnc-commercial-route-reflector.png \ - figures/fig-vnc-commercial-route-reflector.txt \ - figures/fig-vnc-frr-route-reflector.dia \ - figures/fig-vnc-frr-route-reflector.png \ - figures/fig-vnc-frr-route-reflector.txt \ - figures/fig-vnc-gw.dia \ - figures/fig-vnc-gw.png \ - figures/fig-vnc-gw-rr.dia \ - figures/fig-vnc-gw-rr.png \ - figures/fig-vnc-gw-rr.txt \ - figures/fig-vnc-gw.txt \ - figures/fig-vnc-mesh.dia \ - figures/fig-vnc-mesh.png \ - figures/fig-vnc-mesh.txt \ - figures/fig-vnc-redundant-route-reflectors.dia \ - figures/fig-vnc-redundant-route-reflectors.png \ - figures/fig-vnc-redundant-route-reflectors.txt \ - figures/frr-icon.svg \ - figures/frr-logo-icon.png \ - figures/frr-logo-medium.png \ - figures/frr-logo.png \ - figures/frr-logo-small.png \ - figures/git_branches.png \ - figures/git_branches.svg \ - figures/ospf_api_architecture.png \ - figures/ospf_api_msghdr.png \ - figures/ospf_api_msgs1.png \ - figures/ospf_api_msgs2.png \ - extra/frrlexer.py diff --git a/doc/developer/Makefile b/doc/developer/Makefile new file mode 100644 index 0000000000..38afb43a70 --- /dev/null +++ b/doc/developer/Makefile @@ -0,0 +1,16 @@ +all: ALWAYS + @$(MAKE) -s -C ../.. developer-html +help: ALWAYS + @$(MAKE) -s -C ../.. doc/help +pdf: ALWAYS + @$(MAKE) -s -C ../.. doc/developer/_build/latexpdf +info: ALWAYS + @$(MAKE) -s -C ../.. doc/developer/_build/texinfo/frr.info +%: ALWAYS + @$(MAKE) -s -C ../.. doc/developer/_build/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/doc/developer/Makefile.am b/doc/developer/Makefile.am deleted file mode 100644 index 76758f9242..0000000000 --- a/doc/developer/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -# This is necessary to support VPATH builds. -srcdir = @srcdir@ -VPATH = @srcdir@ - -# This variable is used as the documentation source location in frr-sphinx.mk -SOURCESDIR = @srcdir@ - -include @srcdir@/../frr-sphinx.mk diff --git a/doc/developer/building-frr-on-alpine.rst b/doc/developer/building-frr-for-alpine.rst index d303784d4e..d303784d4e 100644 --- a/doc/developer/building-frr-on-alpine.rst +++ b/doc/developer/building-frr-for-alpine.rst diff --git a/doc/developer/building-frr-on-centos6.rst b/doc/developer/building-frr-for-centos6.rst index d50376548f..d4c2c3bfd0 100644 --- a/doc/developer/building-frr-on-centos6.rst +++ b/doc/developer/building-frr-for-centos6.rst @@ -40,98 +40,96 @@ Install required packages Add packages: -:: +.. code-block:: shell - sudo yum install git autoconf automake libtool make gawk \ + sudo yum install git autoconf automake libtool make gawk \ readline-devel texinfo net-snmp-devel groff pkgconfig \ json-c-devel pam-devel flex epel-release perl-XML-LibXML \ c-ares-devel -Install newer version of bison (CentOS 6 package source is too old) from -CentOS 7 +Install newer version of bison (CentOS 6 package source is too old) from CentOS +7: -:: +.. code-block:: shell - sudo yum install rpm-build - curl -O http://vault.centos.org/7.0.1406/os/Source/SPackages/bison-2.7-4.el7.src.rpm - rpmbuild --rebuild ./bison-2.7-4.el7.src.rpm - sudo yum install ./rpmbuild/RPMS/x86_64/bison-2.7-4.el6.x86_64.rpm - rm -rf rpmbuild + sudo yum install rpm-build + curl -O http://vault.centos.org/7.0.1406/os/Source/SPackages/bison-2.7-4.el7.src.rpm + rpmbuild --rebuild ./bison-2.7-4.el7.src.rpm + sudo yum install ./rpmbuild/RPMS/x86_64/bison-2.7-4.el6.x86_64.rpm + rm -rf rpmbuild -Install newer version of autoconf and automake (Package versions are too -old) +Install newer version of autoconf and automake (Package versions are too old): -:: +.. code-block:: shell - curl -O http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz - tar xvf autoconf-2.69.tar.gz - cd autoconf-2.69 - ./configure --prefix=/usr - make - sudo make install - cd .. - - curl -O http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz - tar xvf automake-1.15.tar.gz - cd automake-1.15 - ./configure --prefix=/usr - make - sudo make install - cd .. - -Install ``Python 2.7`` in parallel to default 2.6. Make sure you've -install EPEL (``epel-release`` as above). Then install current -``python27``, ``python27-devel`` and ``pytest`` + curl -O http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz + tar xvf autoconf-2.69.tar.gz + cd autoconf-2.69 + ./configure --prefix=/usr + make + sudo make install + cd .. -:: + curl -O http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz + tar xvf automake-1.15.tar.gz + cd automake-1.15 + ./configure --prefix=/usr + make + sudo make install + cd .. + +Install ``Python 2.7`` in parallel to default 2.6. Make sure you've install +EPEL (``epel-release`` as above). Then install current ``python27``: +``python27-devel`` and ``pytest`` + +.. code-block:: shell - sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm - sudo rpm -ivh https://centos6.iuscommunity.org/ius-release.rpm - sudo yum install python27 python27-pip python27-devel - sudo pip2.7 install pytest + sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm + sudo rpm -ivh https://centos6.iuscommunity.org/ius-release.rpm + sudo yum install python27 python27-pip python27-devel + sudo pip2.7 install pytest -Please note that ``CentOS 6`` needs to keep python pointing to version -2.6 for ``yum`` to keep working, so don't create a symlink for python2.7 -to python +Please note that ``CentOS 6`` needs to keep python pointing to version 2.6 for +``yum`` to keep working, so don't create a symlink for python2.7 to python. -Install newer ``Sphinx-Build`` based on ``Python 2.7`` +Install newer ``Sphinx-Build`` based on ``Python 2.7``. Create a new repo ``/etc/yum.repos.d/puias6.repo`` with the following contents: :: - ### Name: RPM Repository for RHEL 6 - PUIAS (used for Sphinx-Build) - ### URL: http://springdale.math.ias.edu/data/puias/computational - [puias-computational] - name = RPM Repository for RHEL 6 - Sphinx-Build - baseurl = http://springdale.math.ias.edu/data/puias/computational/$releasever/$basearch - #mirrorlist = - enabled = 1 - protect = 0 - gpgkey = - gpgcheck = 0 + ### Name: RPM Repository for RHEL 6 - PUIAS (used for Sphinx-Build) + ### URL: http://springdale.math.ias.edu/data/puias/computational + [puias-computational] + name = RPM Repository for RHEL 6 - Sphinx-Build + baseurl = http://springdale.math.ias.edu/data/puias/computational/$releasever/$basearch + #mirrorlist = + enabled = 1 + protect = 0 + gpgkey = + gpgcheck = 0 Update rpm database & Install newer sphinx -:: +.. code-block:: shell - sudo yum update - sudo yum install python27-sphinx + sudo yum update + sudo yum install python27-sphinx Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not -using any packages** +**This assumes you want to build and install FRR from source and not using any +packages** Add frr groups and user ^^^^^^^^^^^^^^^^^^^^^^^ -:: +.. code-block:: shell - sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvt - sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ + sudo groupadd -g 92 frr + sudo groupadd -r -g 85 frrvt + sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ -c "FRR FRRouting suite" -d /var/run/frr frr Download Source, configure and compile it @@ -140,7 +138,7 @@ Download Source, configure and compile it (You may prefer different options on configure statement. These are just an example.) -:: +.. code-block:: shell git clone https://github.com/frrouting/frr.git frr cd frr @@ -178,32 +176,50 @@ an example.) Create empty FRR configuration files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:: +.. code-block:: shell + + sudo mkdir /var/log/frr + sudo mkdir /etc/frr + +For integrated config file: - sudo mkdir /var/log/frr - sudo mkdir /etc/frr - sudo touch /etc/frr/zebra.conf - sudo touch /etc/frr/bgpd.conf - sudo touch /etc/frr/ospfd.conf - sudo touch /etc/frr/ospf6d.conf - sudo touch /etc/frr/isisd.conf - sudo touch /etc/frr/ripd.conf - sudo touch /etc/frr/ripngd.conf - sudo touch /etc/frr/nhrpd.conf - sudo touch /etc/frr/eigrpd.conf - sudo touch /etc/frr/babeld.conf - sudo chown -R frr:frr /etc/frr/ - sudo touch /etc/frr/vtysh.conf - sudo chown frr:frrvt /etc/frr/vtysh.conf - sudo chmod 640 /etc/frr/*.conf +.. code-block:: shell + + sudo touch /etc/frr/frr.conf + +For individual config files: + +.. note:: Integrated config is preferred to individual config. + +.. code-block:: shell + + sudo touch /etc/frr/babeld.conf + sudo touch /etc/frr/bfdd.conf + sudo touch /etc/frr/bgpd.conf + sudo touch /etc/frr/eigrpd.conf + sudo touch /etc/frr/isisd.conf + sudo touch /etc/frr/ldpd.conf + sudo touch /etc/frr/nhrpd.conf + sudo touch /etc/frr/ospf6d.conf + sudo touch /etc/frr/ospfd.conf + sudo touch /etc/frr/pbrd.conf + sudo touch /etc/frr/pimd.conf + sudo touch /etc/frr/ripd.conf + sudo touch /etc/frr/ripngd.conf + sudo touch /etc/frr/staticd.conf + sudo touch /etc/frr/zebra.conf + sudo chown -R frr:frr /etc/frr/ + sudo touch /etc/frr/vtysh.conf + sudo chown frr:frrvty /etc/frr/vtysh.conf + sudo chmod 640 /etc/frr/*.conf Install daemon config file ^^^^^^^^^^^^^^^^^^^^^^^^^^ -:: +.. code-block:: shell - sudo install -p -m 644 redhat/daemons /etc/frr/ - sudo chown frr:frr /etc/frr/daemons + sudo install -p -m 644 redhat/daemons /etc/frr/ + sudo chown frr:frr /etc/frr/daemons Edit /etc/frr/daemons as needed to select the required daemons ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -214,42 +230,40 @@ Enable the daemons as required by changing the value to ``yes`` Enable IP & IPv6 forwarding ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Edit ``/etc/sysctl.conf`` and set the following values (ignore the other -settings) +Edit :file:`/etc/sysctl.conf` and set the following values (ignore the other +settings):: -:: - - # Controls IP packet forwarding - net.ipv4.ip_forward = 1 - net.ipv6.conf.all.forwarding=1 + # Controls IP packet forwarding + net.ipv4.ip_forward = 1 + net.ipv6.conf.all.forwarding=1 - # Controls source route verification - net.ipv4.conf.default.rp_filter = 0 + # Controls source route verification + net.ipv4.conf.default.rp_filter = 0 Load the modifed sysctl's on the system: -:: +.. code-block:: shell - sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf + sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf Add init.d startup files ^^^^^^^^^^^^^^^^^^^^^^^^ -:: +.. code-block:: - sudo install -p -m 755 redhat/frr.init /etc/init.d/frr - sudo chkconfig --add frr + sudo install -p -m 755 redhat/frr.init /etc/init.d/frr + sudo chkconfig --add frr -Enable frr daemon at startup +Enable FRR daemon at startup ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:: +.. code-block:: - sudo chkconfig frr on + sudo chkconfig frr on Start FRR manually (or reboot) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:: +.. code-block:: - sudo /etc/init.d/frr start + sudo /etc/init.d/frr start diff --git a/doc/developer/building-frr-on-centos7.rst b/doc/developer/building-frr-for-centos7.rst index 31cd4dcc49..31cd4dcc49 100644 --- a/doc/developer/building-frr-on-centos7.rst +++ b/doc/developer/building-frr-for-centos7.rst diff --git a/doc/developer/building-frr-on-debian8.rst b/doc/developer/building-frr-for-debian8.rst index d1e65a472d..d1e65a472d 100644 --- a/doc/developer/building-frr-on-debian8.rst +++ b/doc/developer/building-frr-for-debian8.rst diff --git a/doc/developer/building-frr-on-debian9.rst b/doc/developer/building-frr-for-debian9.rst index 7dad9a7bd4..7dad9a7bd4 100644 --- a/doc/developer/building-frr-on-debian9.rst +++ b/doc/developer/building-frr-for-debian9.rst diff --git a/doc/developer/building-frr-on-fedora24.rst b/doc/developer/building-frr-for-fedora24.rst index 208c580b63..208c580b63 100644 --- a/doc/developer/building-frr-on-fedora24.rst +++ b/doc/developer/building-frr-for-fedora24.rst diff --git a/doc/developer/building-frr-on-freebsd10.rst b/doc/developer/building-frr-for-freebsd10.rst index 5d14db5fa7..95f09e8c22 100644 --- a/doc/developer/building-frr-on-freebsd10.rst +++ b/doc/developer/building-frr-for-freebsd10.rst @@ -78,21 +78,41 @@ an example) Create empty FRR configuration files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:: +.. code-block:: shell + + sudo mkdir /usr/local/etc/frr + +For integrated config file: + +.. code-block:: shell + + sudo touch /usr/local/etc/frr/frr.conf + +For individual config files: + +.. note:: Integrated config is preferred to individual config. + +.. code-block:: shell - sudo mkdir /usr/local/etc/frr - sudo touch /usr/local/etc/frr/zebra.conf - sudo touch /usr/local/etc/frr/bgpd.conf - sudo touch /usr/local/etc/frr/ospfd.conf - sudo touch /usr/local/etc/frr/ospf6d.conf - sudo touch /usr/local/etc/frr/isisd.conf - sudo touch /usr/local/etc/frr/ripd.conf - sudo touch /usr/local/etc/frr/ripngd.conf - sudo touch /usr/local/etc/frr/pimd.conf - sudo chown -R frr:frr /usr/local/etc/frr - sudo touch /usr/local/etc/frr/vtysh.conf - sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf - sudo chmod 640 /usr/local/etc/frr/*.conf + sudo touch /usr/local/etc/frr/babeld.conf + sudo touch /usr/local/etc/frr/bfdd.conf + sudo touch /usr/local/etc/frr/bgpd.conf + sudo touch /usr/local/etc/frr/eigrpd.conf + sudo touch /usr/local/etc/frr/isisd.conf + sudo touch /usr/local/etc/frr/ldpd.conf + sudo touch /usr/local/etc/frr/nhrpd.conf + sudo touch /usr/local/etc/frr/ospf6d.conf + sudo touch /usr/local/etc/frr/ospfd.conf + sudo touch /usr/local/etc/frr/pbrd.conf + sudo touch /usr/local/etc/frr/pimd.conf + sudo touch /usr/local/etc/frr/ripd.conf + sudo touch /usr/local/etc/frr/ripngd.conf + sudo touch /usr/local/etc/frr/staticd.conf + sudo touch /usr/local/etc/frr/zebra.conf + sudo chown -R frr:frr /usr/local/etc/frr/ + sudo touch /usr/local/etc/frr/vtysh.conf + sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf + sudo chmod 640 /usr/local/etc/frr/*.conf Enable IP & IPv6 forwarding ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -101,9 +121,8 @@ Add the following lines to the end of ``/etc/sysctl.conf``: :: - # Routing: We need to forward packets - net.inet.ip.forwarding=1 - net.inet6.ip6.forwarding=1 + # Routing: We need to forward packets + net.inet.ip.forwarding=1 + net.inet6.ip6.forwarding=1 -**Reboot** or use ``sysctl`` to apply the same config to the running -system +**Reboot** or use ``sysctl`` to apply the same config to the running system. diff --git a/doc/developer/building-frr-for-freebsd11.rst b/doc/developer/building-frr-for-freebsd11.rst new file mode 100644 index 0000000000..ce5941440c --- /dev/null +++ b/doc/developer/building-frr-for-freebsd11.rst @@ -0,0 +1,133 @@ +FreeBSD 11 +========== + +FreeBSD 11 restrictions: +------------------------ + +- MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS + +Install required packages +------------------------- + +Add packages: (Allow the install of the package managment tool if this +is first package install and asked) + +.. code-block:: shell + + pkg install git autoconf automake libtool gmake gawk json-c pkgconf \ + bison flex py27-pytest c-ares python3 py36-sphinx texinfo + +Make sure there is no /usr/bin/flex preinstalled (and use the newly +installed in /usr/local/bin): (FreeBSD frequently provides a older flex +as part of the base OS which takes preference in path) + +.. code-block:: shell + + rm -f /usr/bin/flex + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not using any +packages** + +Add frr group and user +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: shell + + pw groupadd frr -g 101 + pw groupadd frrvty -g 102 + pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \ + -d /usr/local/etc/frr -s /usr/sbin/nologin + + +Download Source, configure and compile it +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +(You may prefer different options on configure statement. These are just +an example) + +.. code-block:: shell + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + setenv MAKE gmake + setenv LDFLAGS -L/usr/local/lib + setenv CPPFLAGS -I/usr/local/include + ln -s /usr/local/bin/sphinx-build-3.6 /usr/local/bin/sphinx-build + ./configure \ + --sysconfdir=/usr/local/etc/frr \ + --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ + --localstatedir=/var/run/frr \ + --prefix=/usr/local \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + gmake + gmake check + sudo gmake install + +Create empty FRR configuration files +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: shell + + sudo mkdir /usr/local/etc/frr + +For integrated config file: + +.. code-block:: shell + + sudo touch /usr/local/etc/frr/frr.conf + +For individual config files: + +.. note:: Integrated config is preferred to individual config. + +.. code-block:: shell + + sudo touch /usr/local/etc/frr/babeld.conf + sudo touch /usr/local/etc/frr/bfdd.conf + sudo touch /usr/local/etc/frr/bgpd.conf + sudo touch /usr/local/etc/frr/eigrpd.conf + sudo touch /usr/local/etc/frr/isisd.conf + sudo touch /usr/local/etc/frr/ldpd.conf + sudo touch /usr/local/etc/frr/nhrpd.conf + sudo touch /usr/local/etc/frr/ospf6d.conf + sudo touch /usr/local/etc/frr/ospfd.conf + sudo touch /usr/local/etc/frr/pbrd.conf + sudo touch /usr/local/etc/frr/pimd.conf + sudo touch /usr/local/etc/frr/ripd.conf + sudo touch /usr/local/etc/frr/ripngd.conf + sudo touch /usr/local/etc/frr/staticd.conf + sudo touch /usr/local/etc/frr/zebra.conf + sudo chown -R frr:frr /usr/local/etc/frr/ + sudo touch /usr/local/etc/frr/vtysh.conf + sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf + sudo chmod 640 /usr/local/etc/frr/*.conf + +Enable IP & IPv6 forwarding +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Add the following lines to the end of ``/etc/sysctl.conf``: + +:: + + # Routing: We need to forward packets + net.inet.ip.forwarding=1 + net.inet6.ip6.forwarding=1 + +**Reboot** or use ``sysctl`` to apply the same config to the running system. diff --git a/doc/developer/building-frr-on-freebsd9.rst b/doc/developer/building-frr-for-freebsd9.rst index 02279debea..4f859d3510 100644 --- a/doc/developer/building-frr-on-freebsd9.rst +++ b/doc/developer/building-frr-for-freebsd9.rst @@ -91,21 +91,41 @@ an example) Create empty FRR configuration files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:: +.. code-block:: shell + + sudo mkdir /usr/local/etc/frr + +For integrated config file: + +.. code-block:: shell + + sudo touch /usr/local/etc/frr/frr.conf + +For individual config files: + +.. note:: Integrated config is preferred to individual config. + +.. code-block:: shell - sudo mkdir /usr/local/etc/frr - sudo touch /usr/local/etc/frr/zebra.conf - sudo touch /usr/local/etc/frr/bgpd.conf - sudo touch /usr/local/etc/frr/ospfd.conf - sudo touch /usr/local/etc/frr/ospf6d.conf - sudo touch /usr/local/etc/frr/isisd.conf - sudo touch /usr/local/etc/frr/ripd.conf - sudo touch /usr/local/etc/frr/ripngd.conf - sudo touch /usr/local/etc/frr/pimd.conf - sudo chown -R frr:frr /usr/local/etc/frr - sudo touch /usr/local/etc/frr/vtysh.conf - sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf - sudo chmod 640 /usr/local/etc/frr/*.conf + sudo touch /usr/local/etc/frr/babeld.conf + sudo touch /usr/local/etc/frr/bfdd.conf + sudo touch /usr/local/etc/frr/bgpd.conf + sudo touch /usr/local/etc/frr/eigrpd.conf + sudo touch /usr/local/etc/frr/isisd.conf + sudo touch /usr/local/etc/frr/ldpd.conf + sudo touch /usr/local/etc/frr/nhrpd.conf + sudo touch /usr/local/etc/frr/ospf6d.conf + sudo touch /usr/local/etc/frr/ospfd.conf + sudo touch /usr/local/etc/frr/pbrd.conf + sudo touch /usr/local/etc/frr/pimd.conf + sudo touch /usr/local/etc/frr/ripd.conf + sudo touch /usr/local/etc/frr/ripngd.conf + sudo touch /usr/local/etc/frr/staticd.conf + sudo touch /usr/local/etc/frr/zebra.conf + sudo chown -R frr:frr /usr/local/etc/frr/ + sudo touch /usr/local/etc/frr/vtysh.conf + sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf + sudo chmod 640 /usr/local/etc/frr/*.conf Enable IP & IPv6 forwarding ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,9 +134,8 @@ Add the following lines to the end of ``/etc/sysctl.conf``: :: - # Routing: We need to forward packets - net.inet.ip.forwarding=1 - net.inet6.ip6.forwarding=1 + # Routing: We need to forward packets + net.inet.ip.forwarding=1 + net.inet6.ip6.forwarding=1 -**Reboot** or use ``sysctl`` to apply the same config to the running -system +**Reboot** or use ``sysctl`` to apply the same config to the running system. diff --git a/doc/developer/building-frr-on-netbsd6.rst b/doc/developer/building-frr-for-netbsd6.rst index ca0845d0d0..ca0845d0d0 100644 --- a/doc/developer/building-frr-on-netbsd6.rst +++ b/doc/developer/building-frr-for-netbsd6.rst diff --git a/doc/developer/building-frr-on-netbsd7.rst b/doc/developer/building-frr-for-netbsd7.rst index 86242ef965..86242ef965 100644 --- a/doc/developer/building-frr-on-netbsd7.rst +++ b/doc/developer/building-frr-for-netbsd7.rst diff --git a/doc/developer/building-frr-on-omnios.rst b/doc/developer/building-frr-for-omnios.rst index 03f3845de8..03f3845de8 100644 --- a/doc/developer/building-frr-on-omnios.rst +++ b/doc/developer/building-frr-for-omnios.rst diff --git a/doc/developer/building-frr-on-openbsd6.rst b/doc/developer/building-frr-for-openbsd6.rst index 46db25a025..46db25a025 100644 --- a/doc/developer/building-frr-on-openbsd6.rst +++ b/doc/developer/building-frr-for-openbsd6.rst diff --git a/doc/developer/building-frr-on-ubuntu1204.rst b/doc/developer/building-frr-for-ubuntu1204.rst index 459d411ebc..459d411ebc 100644 --- a/doc/developer/building-frr-on-ubuntu1204.rst +++ b/doc/developer/building-frr-for-ubuntu1204.rst diff --git a/doc/developer/building-frr-on-ubuntu1404.rst b/doc/developer/building-frr-for-ubuntu1404.rst index 681cc30a3b..681cc30a3b 100644 --- a/doc/developer/building-frr-on-ubuntu1404.rst +++ b/doc/developer/building-frr-for-ubuntu1404.rst diff --git a/doc/developer/building-frr-on-ubuntu1604.rst b/doc/developer/building-frr-for-ubuntu1604.rst index 69c4e44d98..69c4e44d98 100644 --- a/doc/developer/building-frr-on-ubuntu1604.rst +++ b/doc/developer/building-frr-for-ubuntu1604.rst diff --git a/doc/developer/building-frr-on-ubuntu1804.rst b/doc/developer/building-frr-for-ubuntu1804.rst index 50e90fc7ea..50e90fc7ea 100644 --- a/doc/developer/building-frr-on-ubuntu1804.rst +++ b/doc/developer/building-frr-for-ubuntu1804.rst diff --git a/doc/developer/building-frr-on-freebsd11.rst b/doc/developer/building-frr-on-freebsd11.rst deleted file mode 100644 index 87fb30226d..0000000000 --- a/doc/developer/building-frr-on-freebsd11.rst +++ /dev/null @@ -1,109 +0,0 @@ -FreeBSD 11 -========================================== - -FreeBSD 11 restrictions: ------------------------- - -- MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use without - MPLS - -Install required packages -------------------------- - -Add packages: (Allow the install of the package managment tool if this -is first package install and asked) - -:: - - pkg install git autoconf automake libtool gmake gawk json-c pkgconf \ - bison flex py27-pytest c-ares python3 py-sphinx - -Make sure there is no /usr/bin/flex preinstalled (and use the newly -installed in /usr/local/bin): (FreeBSD frequently provides a older flex -as part of the base OS which takes preference in path) - -:: - - rm -f /usr/bin/flex - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not -using any packages** - -Add frr group and user -^^^^^^^^^^^^^^^^^^^^^^ - -:: - - pw groupadd frr -g 101 - pw groupadd frrvty -g 102 - pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \ - -d /usr/local/etc/frr -s /usr/sbin/nologin - -(You may prefer different options on configure statement. These are just -an example) - -:: - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - export MAKE=gmake - export LDFLAGS="-L/usr/local/lib" - export CPPFLAGS="-I/usr/local/include" - ./configure \ - --sysconfdir=/usr/local/etc/frr \ - --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ - --localstatedir=/var/run/frr \ - --prefix=/usr/local \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - gmake - gmake check - sudo gmake install - -Create empty FRR configuration files -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -:: - - sudo mkdir /usr/local/etc/frr - sudo touch /usr/local/etc/frr/zebra.conf - sudo touch /usr/local/etc/frr/bgpd.conf - sudo touch /usr/local/etc/frr/ospfd.conf - sudo touch /usr/local/etc/frr/ospf6d.conf - sudo touch /usr/local/etc/frr/isisd.conf - sudo touch /usr/local/etc/frr/ripd.conf - sudo touch /usr/local/etc/frr/ripngd.conf - sudo touch /usr/local/etc/frr/pimd.conf - sudo chown -R frr:frr /usr/local/etc/frr - sudo touch /usr/local/etc/frr/vtysh.conf - sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf - sudo chmod 640 /usr/local/etc/frr/*.conf - -Enable IP & IPv6 forwarding -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Add the following lines to the end of ``/etc/sysctl.conf``: - -:: - - # Routing: We need to forward packets - net.inet.ip.forwarding=1 - net.inet6.ip6.forwarding=1 - -**Reboot** or use ``sysctl`` to apply the same config to the running -system diff --git a/doc/developer/building.rst b/doc/developer/building.rst index d145849f7f..4c18445f9d 100644 --- a/doc/developer/building.rst +++ b/doc/developer/building.rst @@ -7,21 +7,21 @@ Building FRR .. toctree:: :maxdepth: 2 - building-frr-on-alpine - building-frr-on-centos6 - building-frr-on-centos7 - building-frr-on-debian8 - building-frr-on-debian9 - building-frr-on-fedora24 - building-frr-on-freebsd10 - building-frr-on-freebsd11 - building-frr-on-freebsd9 - building-frr-on-netbsd6 - building-frr-on-netbsd7 - building-frr-on-omnios - building-frr-on-openbsd6 + building-frr-for-alpine + building-frr-for-centos6 + building-frr-for-centos7 + building-frr-for-debian8 + building-frr-for-debian9 + building-frr-for-fedora24 + building-frr-for-freebsd10 + building-frr-for-freebsd11 + building-frr-for-freebsd9 + building-frr-for-netbsd6 + building-frr-for-netbsd7 + building-frr-for-omnios + building-frr-for-openbsd6 building-frr-for-openwrt - building-frr-on-ubuntu1204 - building-frr-on-ubuntu1404 - building-frr-on-ubuntu1604 - building-frr-on-ubuntu1804 + building-frr-for-ubuntu1204 + building-frr-for-ubuntu1404 + building-frr-for-ubuntu1604 + building-frr-for-ubuntu1804 diff --git a/doc/developer/subdir.am b/doc/developer/subdir.am new file mode 100644 index 0000000000..43d1290044 --- /dev/null +++ b/doc/developer/subdir.am @@ -0,0 +1,72 @@ +# +# doc/developer +# + +dev_RSTFILES = \ + doc/developer/bgp-typecodes.rst \ + doc/developer/bgpd.rst \ + doc/developer/building-frr-for-openwrt.rst \ + doc/developer/building-frr-for-alpine.rst \ + doc/developer/building-frr-for-centos6.rst \ + doc/developer/building-frr-for-centos7.rst \ + doc/developer/building-frr-for-debian8.rst \ + doc/developer/building-frr-for-debian9.rst \ + doc/developer/building-frr-for-fedora24.rst \ + doc/developer/building-frr-for-freebsd10.rst \ + doc/developer/building-frr-for-freebsd11.rst \ + doc/developer/building-frr-for-freebsd9.rst \ + doc/developer/building-frr-for-netbsd6.rst \ + doc/developer/building-frr-for-netbsd7.rst \ + doc/developer/building-frr-for-omnios.rst \ + doc/developer/building-frr-for-openbsd6.rst \ + doc/developer/building-frr-for-ubuntu1204.rst \ + doc/developer/building-frr-for-ubuntu1404.rst \ + doc/developer/building-frr-for-ubuntu1604.rst \ + doc/developer/building-frr-for-ubuntu1804.rst \ + doc/developer/building.rst \ + doc/developer/cli.rst \ + doc/developer/conf.py \ + doc/developer/hooks.rst \ + doc/developer/index.rst \ + doc/developer/library.rst \ + doc/developer/logging.rst \ + doc/developer/maintainer-release-build.rst \ + doc/developer/memtypes.rst \ + doc/developer/modules.rst \ + doc/developer/next-hop-tracking.rst \ + doc/developer/ospf-api.rst \ + doc/developer/ospf-sr.rst \ + doc/developer/ospf.rst \ + doc/developer/workflow.rst \ + doc/developer/zebra.rst \ + # end + +EXTRA_DIST += \ + $(dev_RSTFILES) \ + doc/developer/draft-zebra-00.ms \ + doc/developer/ldpd-basic-test-setup.md \ + # end + +DEVBUILD = doc/developer/_build +$(DEVBUILD)/.doctrees/environment.pickle: $(dev_RSTFILES) + +# +# nothing built automatically for "all" target. +# + +# +# standard targets +# + +developer-info: $(DEVBUILD)/texinfo/frr.info +developer-html: $(DEVBUILD)/html/.buildinfo +developer-pdf: $(DEVBUILD)/latexpdf + +# +# hook-in for clean +# + +.PHONY: clean-devdocs +clean-local: clean-devdocs +clean-devdocs: + -rm -rf "$(DEVBUILD)" diff --git a/doc/frr-sphinx.mk b/doc/frr-sphinx.mk deleted file mode 100644 index 3e4c67d374..0000000000 --- a/doc/frr-sphinx.mk +++ /dev/null @@ -1,229 +0,0 @@ -# Makefile for Sphinx documentation -# - -# Sphinx is not designed to be invoked multiple times against the same toctree. -.NOTPARALLEL: - -# You can set these variables from the command line. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -PAPER ?= -BUILDDIR = _build - -# This is a custom FRR variable just for this docs subdirectory used to support -# VPATH builds. Makefiles which include this file should override it to point -# to the correct sources path. -SOURCESDIR ?= . - -# User-friendly check for sphinx-build -ifneq ($(MAKECMDGOALS), clean) - ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) - SPHINXBUILD = sphinx-1.0-build - endif - ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) - $(error "The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/") - endif -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCESDIR) -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCESDIR) - -.PHONY: help -help: - @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - -.PHONY: clean -clean: - rm -rf $(BUILDDIR)/* - -.PHONY: html -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -.PHONY: dirhtml -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -.PHONY: singlehtml -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -.PHONY: pickle -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -.PHONY: json -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -.PHONY: htmlhelp -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -.PHONY: qthelp -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/FRR.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/FRR.qhc" - -.PHONY: applehelp -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -.PHONY: devhelp -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/FRR" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/FRR" - @echo "# devhelp" - -.PHONY: epub -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -.PHONY: latex -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -.PHONY: latexpdf -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: latexpdfja -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: text -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -.PHONY: man -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -.PHONY: texinfo -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -.PHONY: info -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - $(MAKE) -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -.PHONY: gettext -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -.PHONY: changes -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -.PHONY: linkcheck -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -.PHONY: doctest -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -.PHONY: coverage -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -.PHONY: xml -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -.PHONY: pseudoxml -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/manpages/Makefile b/doc/manpages/Makefile new file mode 100644 index 0000000000..7cccfa2a3d --- /dev/null +++ b/doc/manpages/Makefile @@ -0,0 +1,12 @@ +all: ALWAYS + @$(MAKE) -s -C ../.. doc/manpages/man.stamp +help: ALWAYS + @$(MAKE) -s -C ../.. doc/help +%: ALWAYS + @$(MAKE) -s -C ../.. doc/manpages/_build/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am deleted file mode 100644 index 009c723823..0000000000 --- a/doc/manpages/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -# This is necessary to support VPATH builds. -srcdir = @srcdir@ -VPATH = @srcdir@ - -# This variable is used as the documentation source location in frr-sphinx.mk -SOURCESDIR = @srcdir@ - -include @srcdir@/../frr-sphinx.mk - -# ----------------------------------------------------------------------------- -# Automake requires that 3rd-party Makefiles recognize these targets. -# ----------------------------------------------------------------------------- -# install -# install-data -# install-exec -# uninstall -# install-dvi -# install-html -# install-info -# install-ps -# install-pdf -# installdirs -# check -# installcheck -# mostlyclean -# clean -# distclean -# maintainer-clean -# dvi -# pdf -# ps -# info -# html -# tags -# ctags - -# These targets are automatically generated by Sphinx but conflict with -# implicitly defined Automake rules, so we manually override them to nothing. -# The other option is deleting the Sphinx-generated rules, which suppresses the -# warning but kinda screws up the symmetry between Makefiles. -info: ; -html: ; - -all: man - -install-data: man - -install: install-data diff --git a/doc/manpages/subdir.am b/doc/manpages/subdir.am new file mode 100644 index 0000000000..24f47fc7a5 --- /dev/null +++ b/doc/manpages/subdir.am @@ -0,0 +1,139 @@ +# +# doc/manpages +# + +man_RSTFILES = \ + doc/manpages/bgpd.rst \ + doc/manpages/common-options.rst \ + doc/manpages/conf.py \ + doc/manpages/defines.rst \ + doc/manpages/eigrpd.rst \ + doc/manpages/epilogue.rst \ + doc/manpages/frr.rst \ + doc/manpages/index.rst \ + doc/manpages/isisd.rst \ + doc/manpages/ldpd.rst \ + doc/manpages/mtracebis.rst \ + doc/manpages/nhrpd.rst \ + doc/manpages/ospf6d.rst \ + doc/manpages/ospfclient.rst \ + doc/manpages/ospfd.rst \ + doc/manpages/pimd.rst \ + doc/manpages/ripd.rst \ + doc/manpages/pbrd.rst \ + doc/manpages/ripngd.rst \ + doc/manpages/sharpd.rst \ + doc/manpages/staticd.rst \ + doc/manpages/vtysh.rst \ + doc/manpages/watchfrr.rst \ + doc/manpages/zebra.rst \ + doc/manpages/bfdd.rst \ + doc/manpages/bfd-options.rst \ + # end + +EXTRA_DIST += $(man_RSTFILES) + +MANBUILD = doc/manpages/_build/man +doc/manpages/_build/.doctrees/environment.pickle: $(man_RSTFILES) + +# +# automake integration +# + +rstman1dir = $(mandir)/man1 +rstman8dir = $(mandir)/man8 + +rstman1_DATA = +rstman8_DATA = + +rstman1_DATA += $(MANBUILD)/frr.1 + +if PIMD +rstman8_DATA += $(MANBUILD)/pimd.8 +rstman8_DATA += $(MANBUILD)/mtracebis.8 +endif + +if PBRD +rstman8_DATA += $(MANBUILD)/pbrd.8 +endif + +if BGPD +rstman8_DATA += $(MANBUILD)/bgpd.8 +endif + +if ISISD +rstman8_DATA += $(MANBUILD)/isisd.8 +endif + +if OSPF6D +rstman8_DATA += $(MANBUILD)/ospf6d.8 +endif + +if OSPFCLIENT +rstman8_DATA += $(MANBUILD)/ospfclient.8 +endif + +if OSPFD +rstman8_DATA += $(MANBUILD)/ospfd.8 +endif + +if LDPD +rstman8_DATA += $(MANBUILD)/ldpd.8 +endif + +if RIPD +rstman8_DATA += $(MANBUILD)/ripd.8 +endif + +if RIPNGD +rstman8_DATA += $(MANBUILD)/ripngd.8 +endif + +if NHRPD +rstman8_DATA += $(MANBUILD)/nhrpd.8 +endif + +if VTYSH +rstman1_DATA += $(MANBUILD)/vtysh.1 +endif + +if WATCHFRR +rstman8_DATA += $(MANBUILD)/watchfrr.8 +endif + +if ZEBRA +rstman8_DATA += $(MANBUILD)/zebra.8 +endif + +if EIGRPD +rstman8_DATA += $(MANBUILD)/eigrpd.8 +endif + +if SHARPD +rstman8_DATA += $(MANBUILD)/sharpd.8 +endif + +if STATICD +rstman8_DATA += $(MANBUILD)/staticd.8 +endif + +if BFDD +rstman8_DATA += $(MANBUILD)/bfdd.8 +endif + +# dependency +$(rstman8_DATA) $(rstman1_DATA): $(MANBUILD)/man.stamp + +# +# hook-ins for clean / doc +# (install is handled by automake _DATA) +# + +clean-local: clean-manpages +.PHONY: clean-manpages +clean-manpages: + -rm -rf $(MANBUILD) + +doc: doc-man +.PHONY: doc-man +doc-man: $(rstman8_DATA) $(rstman1_DATA) diff --git a/doc/subdir.am b/doc/subdir.am new file mode 100644 index 0000000000..4170101655 --- /dev/null +++ b/doc/subdir.am @@ -0,0 +1,176 @@ +# +# doc +# + +# You can set these variables from the command line. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +PAPER ?= + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) + +### + +AM_V_SPHINX = $(am__v_SPHINX_$(V)) +am__v_SPHINX_ = $(am__v_SPHINX_$(AM_DEFAULT_VERBOSITY)) +am__v_SPHINX_0 = @echo " SPHINX " $@; +am__v_SPHINX_1 = +AM_V_MAKEINFO = $(am__v_MAKEINFO_$(V)) +am__v_MAKEINFO_ = $(am__v_MAKEINFO_$(AM_DEFAULT_VERBOSITY)) +am__v_MAKEINFO_0 = @echo " MAKEINFO" $@; +am__v_MAKEINFO_1 = + +# +# real-file sphinx targets that work for dependencies +# + +doc/%/_build/.doctrees/environment.pickle: + $(AM_V_SPHINX) ( \ + subdoc="$@"; subdoc="$${subdoc#doc/}"; subdoc="doc/$${subdoc%%/*}"; \ + $(SPHINXBUILD) -a -q -b text -d "$${subdoc}/_build/.doctrees" \ + $(ALLSPHINXOPTS) "$(top_srcdir)/$${subdoc}" "$${subdoc}/_build/text" \ + ) +doc/%/_build/html/.buildinfo: doc/%/_build/.doctrees/environment.pickle + $(AM_V_SPHINX) ( \ + subdoc="$@"; subdoc="$${subdoc#doc/}"; subdoc="doc/$${subdoc%%/*}"; \ + $(SPHINXBUILD) -q -b html -d "$${subdoc}/_build/.doctrees" \ + $(ALLSPHINXOPTS) "$(top_srcdir)/$${subdoc}" "$${subdoc}/_build/html" \ + ) +.PRECIOUS: doc/%/_build/texinfo/frr.texi +doc/%/_build/texinfo/frr.texi: doc/%/_build/.doctrees/environment.pickle + $(AM_V_SPHINX) ( \ + subdoc="$@"; subdoc="$${subdoc#doc/}"; subdoc="doc/$${subdoc%%/*}"; \ + $(SPHINXBUILD) -q -b texinfo -d "$${subdoc}/_build/.doctrees" \ + $(ALLSPHINXOPTS) "$(top_srcdir)/$${subdoc}" "$${subdoc}/_build/texinfo" \ + ) +doc/%/_build/texinfo/frr.info: doc/%/_build/texinfo/frr.texi + $(AM_V_MAKEINFO)$(MAKEINFO) --no-split -o '$@' '$<' +doc/%/_build/man/man.stamp: doc/%/_build/.doctrees/environment.pickle + $(AM_V_SPHINX) ( \ + subdoc="$@"; subdoc="$${subdoc#doc/}"; subdoc="doc/$${subdoc%%/*}"; \ + $(MKDIR_P) "$${subdoc}/_build/man"; touch $@.tmp; \ + $(SPHINXBUILD) -a -q -b man -d "$${subdoc}/_build/.doctrees" \ + $(ALLSPHINXOPTS) "$(top_srcdir)/$${subdoc}" "$${subdoc}/_build/man" && \ + mv $@.tmp $@ \ + ) + +# +# auxiliary sphinx targets (output name = directory, +# deps will not work very well) +# + +SPHINXTARGETS = \ + html dirhtml singlehtml pickle json \ + htmlhelp qthelp applehelp devhelp \ + epub latex text man texinfo gettext \ + changes linkcheck doctest coverage \ + xml pseudoxml \ + # end + +M_SPHINXTARGETS = $(addprefix doc/%/_build/,$(SPHINXTARGETS)) +.PRECIOUS: $(M_SPHINXTARGETS) +$(M_SPHINXTARGETS): doc/%/_build/.doctrees/environment.pickle + $(AM_V_SPHINX) ( \ + target="$@"; \ + builder="$${target##*/}"; \ + subdoc="$${target#doc/}"; subdoc="doc/$${subdoc%%/*}"; \ + rm -rf "$@"; \ + $(SPHINXBUILD) -q -b $${builder} -d $${subdoc}/_build/.doctrees \ + $(ALLSPHINXOPTS) $(top_srcdir)/$${subdoc} $@ \ + ) + +.PHONY: doc/%/_build/latexpdf +doc/%/_build/latexpdf: doc/%/_build/latex + @make -C $< all-pdf + +# If you want to build the developer's docs in other formats, try the +# following: +# +# $ cd developer +# $ make help + +# dist tarballs want doc sources +EXTRA_DIST += \ + doc/mpls/ChangeLog.opaque.txt \ + doc/mpls/ospfd.conf \ + doc/mpls/cli_summary.txt \ + doc/mpls/opaque_lsa.txt \ + doc/figures/cligraph.png \ + doc/figures/cligraph.svg \ + doc/figures/fig-normal-processing.dia \ + doc/figures/fig-normal-processing.png \ + doc/figures/fig-normal-processing.txt \ + doc/figures/fig-rs-processing.dia \ + doc/figures/fig-rs-processing.png \ + doc/figures/fig-rs-processing.txt \ + doc/figures/fig_topologies_full.dia \ + doc/figures/fig_topologies_full.png \ + doc/figures/fig_topologies_full.txt \ + doc/figures/fig_topologies_rs.dia \ + doc/figures/fig_topologies_rs.png \ + doc/figures/fig_topologies_rs.txt \ + doc/figures/fig-vnc-commercial-route-reflector.dia \ + doc/figures/fig-vnc-commercial-route-reflector.png \ + doc/figures/fig-vnc-commercial-route-reflector.txt \ + doc/figures/fig-vnc-frr-route-reflector.dia \ + doc/figures/fig-vnc-frr-route-reflector.png \ + doc/figures/fig-vnc-frr-route-reflector.txt \ + doc/figures/fig-vnc-gw.dia \ + doc/figures/fig-vnc-gw.png \ + doc/figures/fig-vnc-gw-rr.dia \ + doc/figures/fig-vnc-gw-rr.png \ + doc/figures/fig-vnc-gw-rr.txt \ + doc/figures/fig-vnc-gw.txt \ + doc/figures/fig-vnc-mesh.dia \ + doc/figures/fig-vnc-mesh.png \ + doc/figures/fig-vnc-mesh.txt \ + doc/figures/fig-vnc-redundant-route-reflectors.dia \ + doc/figures/fig-vnc-redundant-route-reflectors.png \ + doc/figures/fig-vnc-redundant-route-reflectors.txt \ + doc/figures/frr-icon.svg \ + doc/figures/frr-logo-icon.png \ + doc/figures/frr-logo-medium.png \ + doc/figures/frr-logo.png \ + doc/figures/frr-logo-small.png \ + doc/figures/git_branches.png \ + doc/figures/git_branches.svg \ + doc/figures/ospf_api_architecture.png \ + doc/figures/ospf_api_msghdr.png \ + doc/figures/ospf_api_msgs1.png \ + doc/figures/ospf_api_msgs2.png \ + doc/extra/frrlexer.py \ + # end + + +.PHONY: doc/help +doc/help: + @echo "Please use \`make doc/{user,manpages,developer}/<target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " applehelp to make an Apple Help Book" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" diff --git a/doc/user/Makefile b/doc/user/Makefile new file mode 100644 index 0000000000..840ee5b8a9 --- /dev/null +++ b/doc/user/Makefile @@ -0,0 +1,16 @@ +all: ALWAYS + @$(MAKE) -s -C ../.. doc-user +help: ALWAYS + @$(MAKE) -s -C ../.. doc/help +pdf: ALWAYS + @$(MAKE) -s -C ../.. doc/user/_build/latexpdf +info: ALWAYS + @$(MAKE) -s -C ../.. doc/user/_build/texinfo/frr.info +%: ALWAYS + @$(MAKE) -s -C ../.. doc/user/_build/$@ + +Makefile: + #nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/doc/user/Makefile.am b/doc/user/Makefile.am deleted file mode 100644 index 64af2ff145..0000000000 --- a/doc/user/Makefile.am +++ /dev/null @@ -1,55 +0,0 @@ -# This is necessary to support VPATH builds. -srcdir = @srcdir@ -VPATH = @srcdir@ - -# This variable is used as the documentation source location in frr-sphinx.mk -SOURCESDIR = @srcdir@ - -include @srcdir@/../frr-sphinx.mk - -# ----------------------------------------------------------------------------- -# Automake requires that 3rd-party Makefiles recognize these targets. -# ----------------------------------------------------------------------------- -# install -# install-data -# install-exec -# uninstall -# install-dvi -# install-html -# install-info -# install-ps -# install-pdf -# installdirs -# check -# installcheck -# mostlyclean -# clean -# distclean -# maintainer-clean -# dvi -# pdf -# ps -# info -# html -# tags -# ctags - -# When building 'all', the logic is that we want to make docs that are easily -# readable by the person that just built them. Technically the reST source is -# readable in its own right, but we'll also build info and html because those -# offer sequentially better reading experiences. PDF is not built by default -# because it takes quite a while. -all: info - -# info and html already have built-in sphinx rules; pdf goes to latexpdf -pdf: latexpdf - -# install user manual as info file -install-info: info - install -d ${DESTDIR}${infodir} - gzip < _build/texinfo/frr.info > ${DESTDIR}${infodir}/frr.info.gz - install-info _build/texinfo/frr.info ${DESTDIR}${infodir}/dir - -install-data: install-info - -install: install-data diff --git a/doc/user/_static/overrides.css b/doc/user/_static/overrides.css index 3143f8bb65..41fcc66f8d 100644 --- a/doc/user/_static/overrides.css +++ b/doc/user/_static/overrides.css @@ -19,11 +19,6 @@ table.mark th { table.mark td { vertical-align: middle; } -table.mark td[colspan="7"] { - text-align: center; - padding-top: 8pt; - padding-bottom: 2pt; -} table.mark cite { font-weight: bold; } @@ -32,6 +27,13 @@ table.mark cite { td.mark { width: 4.5em; } +table.mark strong { + display:block; + text-align: center; + margin:auto; + padding-top: 8pt; + padding-bottom: 2pt; +} td.mark span { display: block; padding: 3px 1px; @@ -39,6 +41,12 @@ td.mark span { width: 36pt; margin:auto; } +table.mark tr td:first-child { + padding-left:1.5em; +} +table.mark tr td:first-child cite { + margin-left:-1.5em; +} span.mark-y { background-color: #77ffaa; } span.mark-geq { background-color: #aaff77; } span.mark-cp { background-color: #ffbb55; } diff --git a/doc/user/overview.rst b/doc/user/overview.rst index 51bd6228e3..e90b84b02b 100644 --- a/doc/user/overview.rst +++ b/doc/user/overview.rst @@ -166,69 +166,69 @@ features with system dependencies are included here. will look somewhat shoddy on other sphinx targets like PDF or info (but should still be readable.) -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ | Daemon / Feature | Linux | OpenBSD | FreeBSD | NetBSD | Solaris | -+==+================================+================+==============+============+============+============+ -| FRR Core | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++===================================+================+==============+============+============+============+ +| **FRR Core** | | | | | | ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `zebra` | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | VRF | :mark:`≥4.8` | :mark:`N` | :mark:`N` | :mark:`N` | :mark:`N` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | MPLS | :mark:`≥4.5` | :mark:`Y` | :mark:`N` | :mark:`N` | :mark:`N` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| VRF | :mark:`≥4.8` | :mark:`N` | :mark:`N` | :mark:`N` | :mark:`N` | ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| MPLS | :mark:`≥4.5` | :mark:`Y` | :mark:`N` | :mark:`N` | :mark:`N` | ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `pbrd` (Policy Routing) | :mark:`Y` | :mark:`N` | :mark:`N` | :mark:`N` | :mark:`N` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| WAN / Carrier protocols | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| **WAN / Carrier protocols** | | | | | | ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `bgpd` (BGP) | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | VRF / L3VPN | :mark:`≥4.8` | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | -| | | :mark:`†4.3` | | | | | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | EVPN | :mark:`≥4.18` | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | -| | | :mark:`†4.9` | | | | | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | VNC (Virtual Network Control) | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | Flowspec | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| VRF / L3VPN | :mark:`≥4.8` | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | +| | :mark:`†4.3` | | | | | ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| EVPN | :mark:`≥4.18` | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | +| | :mark:`†4.9` | | | | | ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| VNC (Virtual Network Control) | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| Flowspec | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | :mark:`CP` | ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `ldpd` (LDP) | :mark:`≥4.5` | :mark:`Y` | :mark:`N` | :mark:`N` | :mark:`N` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | VPWS / PW | :mark:`N` | :mark:`≥5.8` | :mark:`N` | :mark:`N` | :mark:`N` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | VPLS | :mark:`N` | :mark:`≥5.8` | :mark:`N` | :mark:`N` | :mark:`N` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| VPWS / PW | :mark:`N` | :mark:`≥5.8` | :mark:`N` | :mark:`N` | :mark:`N` | ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| VPLS | :mark:`N` | :mark:`≥5.8` | :mark:`N` | :mark:`N` | :mark:`N` | ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `nhrpd` (NHRP) | :mark:`Y` | :mark:`N` | :mark:`N` | :mark:`N` | :mark:`N` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| Link-State Routing | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| **Link-State Routing** | | | | | | ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `ospfd` (OSPFv2) | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | Segment Routing | :mark:`≥4.12` | :mark:`N` | :mark:`N` | :mark:`N` | :mark:`N` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| Segment Routing | :mark:`≥4.12` | :mark:`N` | :mark:`N` | :mark:`N` | :mark:`N` | ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `ospf6d` (OSPFv3) | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `isisd` (IS-IS) | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| Distance-Vector Routing | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| **Distance-Vector Routing** | | | | | | ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `ripd` (RIPv2) | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `ripngd` (RIPng) | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `babeld` (BABEL) | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `eigrpd` (EIGRP) | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| Multicast Routing | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| **Multicast Routing** | | | | | | ++-----------------------------------+----------------+--------------+------------+------------+------------+ | `pimd` (PIM) | :mark:`≥4.18` | :mark:`N` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | SSM (Source Specific) | :mark:`Y` | :mark:`N` | :mark:`Y` | :mark:`Y` | :mark:`Y` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ -| | ASM (Any Source) | :mark:`Y` | :mark:`N` | :mark:`N` | :mark:`N` | :mark:`N` | -+--+--------------------------------+----------------+--------------+------------+------------+------------+ ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| SSM (Source Specific) | :mark:`Y` | :mark:`N` | :mark:`Y` | :mark:`Y` | :mark:`Y` | ++-----------------------------------+----------------+--------------+------------+------------+------------+ +| ASM (Any Source) | :mark:`Y` | :mark:`N` | :mark:`N` | :mark:`N` | :mark:`N` | ++-----------------------------------+----------------+--------------+------------+------------+------------+ The indicators have the following semantics: diff --git a/doc/user/sharp.rst b/doc/user/sharp.rst index e27da63b53..8831c0159b 100644 --- a/doc/user/sharp.rst +++ b/doc/user/sharp.rst @@ -33,13 +33,14 @@ All sharp commands are under the enable node and preceeded by the ``sharp`` keyword. At present, no sharp commands will be preserved in the config. .. index:: sharp install -.. clicmd:: sharp install routes A.B.C.D nexthop E.F.G.H (1-1000000) +.. clicmd:: sharp install routes A.B.C.D nexthop <E.F.G.H|X:X::X:X> (1-1000000) Install up to 1,000,000 (one million) /32 routes starting at ``A.B.C.D`` - with specified nexthop ``E.F.G.H``. The nexthop is a ``NEXTHOP_TYPE_IPV4`` - and must be reachable to be installed into the kernel. The routes are - installed into zebra as ``ZEBRA_ROUTE_SHARP`` and can be used as part of a - normal route redistribution. Route installation time is noted in the debug + with specified nexthop ``E.F.G.H`` or ``X:X::X:X``. The nexthop is + a ``NEXTHOP_TYPE_IPV4`` or ``NEXTHOP_TYPE_IPV6`` and must be reachable + to be installed into the kernel. The routes are installed into zebra as + ``ZEBRA_ROUTE_SHARP`` and can be used as part of a normal route + redistribution. Route installation time is noted in the debug log. When zebra successfully installs a route into the kernel and SHARP receives success notifications for all routes this is logged as well. diff --git a/doc/user/subdir.am b/doc/user/subdir.am new file mode 100644 index 0000000000..6e51eed9d1 --- /dev/null +++ b/doc/user/subdir.am @@ -0,0 +1,110 @@ +# +# doc/user +# + +user_RSTFILES = \ + doc/user/babeld.rst \ + doc/user/ldpd.rst \ + doc/user/basic.rst \ + doc/user/bgp.rst \ + doc/user/bugs.rst \ + doc/user/conf.py \ + doc/user/eigrpd.rst \ + doc/user/filter.rst \ + doc/user/glossary.rst \ + doc/user/index.rst \ + doc/user/installation.rst \ + doc/user/ipv6.rst \ + doc/user/isisd.rst \ + doc/user/kernel.rst \ + doc/user/nhrpd.rst \ + doc/user/ospf6d.rst \ + doc/user/ospfd.rst \ + doc/user/ospf_fundamentals.rst \ + doc/user/overview.rst \ + doc/user/packet-dumps.rst \ + doc/user/pim.rst \ + doc/user/ripd.rst \ + doc/user/pbr.rst \ + doc/user/ripngd.rst \ + doc/user/routemap.rst \ + doc/user/routeserver.rst \ + doc/user/rpki.rst \ + doc/user/setup.rst \ + doc/user/sharp.rst \ + doc/user/snmp.rst \ + doc/user/snmptrap.rst \ + doc/user/static.rst \ + doc/user/vnc.rst \ + doc/user/vtysh.rst \ + doc/user/zebra.rst \ + doc/user/bfd.rst \ + doc/user/flowspec.rst \ + # end + +EXTRA_DIST += \ + $(user_RSTFILES) \ + doc/user/Useful_Sysctl_Settings.md \ + # end + +USERBUILD = doc/user/_build +$(USERBUILD)/.doctrees/environment.pickle: $(user_RSTFILES) + +# +# automake integration (things that should be built in "all") +# + +if DOC +nodist_noinst_DATA += $(USERBUILD)/texinfo/frr.info +endif +if DOC_HTML +nodist_noinst_DATA += $(USERBUILD)/html/.buildinfo +endif + +# +# standard targets +# + +.PHONY: info html pdf +info: $(USERBUILD)/texinfo/frr.info +html: $(USERBUILD)/html/.buildinfo +pdf: $(USERBUILD)/latexpdf + +# +# hook-ins for clean / install / doc +# + +.PHONY: clean-userdocs +clean-local: clean-userdocs +clean-userdocs: + -rm -rf "$(USERBUILD)" + +# INSTALL_INFO=install-info +.PHONY: install-info uninstall-info install-html uninstall-html + +install-info: $(USERBUILD)/texinfo/frr.info + $(MKDIR_P) "$(DESTDIR)$(infodir)" + $(INSTALL_DATA) "$<" "$(DESTDIR)$(infodir)" + [ -z "${DESTDIR}" ] && $(INSTALL_INFO) --info-dir="$(DESTDIR)$(infodir)" "$<" || true +uninstall-info: $(USERBUILD)/texinfo/frr.info + -rm -f "$(DESTDIR)$(infodir)/$<" + [ -z "${DESTDIR}" ] && $(INSTALL_INFO) --delete --info-dir="$(DESTDIR)$(infodir)" "$<" || true + +install-html: $(USERBUILD)/html/.buildinfo + $(MKDIR_P) "$(DESTDIR)$(htmldir)" + cp -r "$(USERBUILD)/html" "$(DESTDIR)$(htmldir)" +uninstall-html: + -rm -rf "$(DESTDIR)$(htmldir)/html" + +.PHONY: install-data-local uninstall-local +if DOC +DOC_INFO=info +install-data-local: install-info +uninstall-local: uninstall-info +endif +if DOC_HTML +DOC_HTML=html +install-data-local: install-html +uninstall-local: uninstall-html +endif +doc: $(DOC_INFO) $(DOC_HTML) diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 85f2a7af3e..e3e5d1325a 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -395,8 +395,6 @@ be updated with the new name. To illustrate, if you want to recompile with ./configure --with-defaultvrfname=global -More information about the option in :ref:`_frr-configuration`. - .. _zebra-mpls: MPLS Commands diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 190c18777e..311fbce4ab 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -1085,7 +1085,7 @@ DEFUN (eigrp_redistribute_source_metric, DEFUN (no_eigrp_redistribute_source_metric, no_eigrp_redistribute_source_metric_cmd, "no redistribute " FRR_REDIST_STR_EIGRPD - " metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)", + " [metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)]", "Disable\n" REDIST_STR FRR_REDIST_HELP_STR_EIGRPD diff --git a/lib/agg_table.c b/lib/agg_table.c new file mode 100644 index 0000000000..6033fc3f05 --- /dev/null +++ b/lib/agg_table.c @@ -0,0 +1,59 @@ +/* + * Aggregate Route + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * 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 "agg_table.h" + + +static struct route_node *agg_node_create(route_table_delegate_t *delegate, + struct route_table *table) +{ + struct agg_node *node; + + node = XCALLOC(MTYPE_TMP, sizeof(struct agg_node)); + + return agg_node_to_rnode(node); +} + +static void agg_node_destroy(route_table_delegate_t *delegate, + struct route_table *table, struct route_node *node) + +{ + struct agg_node *anode = agg_node_from_rnode(node); + + XFREE(MTYPE_TMP, anode); +} + +route_table_delegate_t agg_table_delegate = { + .create_node = agg_node_create, + .destroy_node = agg_node_destroy, +}; + +struct agg_table *agg_table_init(void) +{ + struct agg_table *at; + + at = XCALLOC(MTYPE_TMP, sizeof(struct agg_table)); + + at->route_table = route_table_init_with_delegate(&agg_table_delegate); + at->route_table->info = at; + + return at; +} diff --git a/lib/agg_table.h b/lib/agg_table.h new file mode 100644 index 0000000000..235f0d37a3 --- /dev/null +++ b/lib/agg_table.h @@ -0,0 +1,153 @@ +/* + * agg_table - Aggregate Table Header + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * 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 __AGG_TABLE_H__ +#define __AGG_TABLE_H__ + +#include "prefix.h" +#include "table.h" + +struct agg_table { + struct route_table *route_table; + + void *info; +}; + +struct agg_node { + /* + * Caution these must be the very first fields + * @see agg_node_to_rnode + * @see agg_node_from_rnode + */ + ROUTE_NODE_FIELDS + + /* Aggregation. */ + void *aggregate; +}; + +static inline struct route_node *agg_node_to_rnode(struct agg_node *node) +{ + return (struct route_node *)node; +} + +static inline struct agg_node *agg_node_from_rnode(struct route_node *node) +{ + return (struct agg_node *)node; +} + +static inline struct agg_node *agg_lock_node(struct agg_node *node) +{ + return (struct agg_node *)route_lock_node(agg_node_to_rnode(node)); +} + +static inline void agg_unlock_node(struct agg_node *node) +{ + return route_unlock_node(agg_node_to_rnode(node)); +} + +static inline void agg_set_table_info(struct agg_table *atable, void *data) +{ + atable->info = data; +} + +static inline void *agg_get_table_info(struct agg_table *atable) +{ + return atable->info; +} + +static inline struct agg_node *agg_route_top(struct agg_table *table) +{ + return agg_node_from_rnode(route_top(table->route_table)); +} + +static inline struct agg_node *agg_route_next(struct agg_node *node) +{ + return agg_node_from_rnode(route_next(agg_node_to_rnode(node))); +} + +static inline struct agg_node *agg_node_get(struct agg_table *table, + struct prefix *p) +{ + return agg_node_from_rnode(route_node_get(table->route_table, p)); +} + +static inline struct agg_node * +agg_node_lookup(const struct agg_table *const table, struct prefix *p) +{ + return agg_node_from_rnode(route_node_lookup(table->route_table, p)); +} + +static inline struct agg_node *agg_route_next_until(struct agg_node *node, + struct agg_node *limit) +{ + struct route_node *rnode; + + rnode = route_next_until(agg_node_to_rnode(node), + agg_node_to_rnode(limit)); + + return agg_node_from_rnode(rnode); +} + +static inline struct agg_node *agg_node_match(struct agg_table *table, + struct prefix *p) +{ + return agg_node_from_rnode(route_node_match(table->route_table, p)); +} + +static inline struct agg_node *agg_node_parent(struct agg_node *node) +{ + struct route_node *rn = agg_node_to_rnode(node); + + return agg_node_from_rnode(rn->parent); +} + +static inline struct agg_node *agg_node_left(struct agg_node *node) +{ + struct route_node *rn = agg_node_to_rnode(node); + + return agg_node_from_rnode(rn->l_left); +} + +static inline struct agg_node *agg_node_right(struct agg_node *node) +{ + struct route_node *rn = agg_node_to_rnode(node); + + return agg_node_from_rnode(rn->l_right); +} + +extern struct agg_table *agg_table_init(void); + +static inline void agg_table_finish(struct agg_table *atable) +{ + route_table_finish(atable->route_table); + atable->route_table = NULL; + + XFREE(MTYPE_TMP, atable); +} + +static inline struct agg_node *agg_route_table_top(struct agg_node *node) +{ + return (struct agg_node *)route_top(node->table); +} + +static inline struct agg_table *agg_get_table(struct agg_node *node) +{ + return (struct agg_table *)node->table->info; +} +#endif @@ -342,7 +342,7 @@ static void bfd_last_update(time_t last_update, char *buf, size_t len) * bfd_show_param - Show the BFD parameter information. */ void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag, - int extra_space, uint8_t use_json, json_object *json_obj) + int extra_space, bool use_json, json_object *json_obj) { json_object *json_bfd = NULL; @@ -378,7 +378,7 @@ void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag, * bfd_show_status - Show the BFD status information. */ static void bfd_show_status(struct vty *vty, struct bfd_info *bfd_info, - int bfd_tag, int extra_space, uint8_t use_json, + int bfd_tag, int extra_space, bool use_json, json_object *json_bfd) { char time_buf[32]; @@ -402,7 +402,7 @@ static void bfd_show_status(struct vty *vty, struct bfd_info *bfd_info, * bfd_show_info - Show the BFD information. */ void bfd_show_info(struct vty *vty, struct bfd_info *bfd_info, int multihop, - int extra_space, uint8_t use_json, json_object *json_obj) + int extra_space, bool use_json, json_object *json_obj) { json_object *json_bfd = NULL; @@ -91,11 +91,11 @@ extern struct interface *bfd_get_peer_info(struct stream *s, struct prefix *dp, const char *bfd_get_status_str(int status); extern void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, - int bfd_tag, int extra_space, uint8_t use_json, + int bfd_tag, int extra_space, bool use_json, json_object *json_obj); extern void bfd_show_info(struct vty *vty, struct bfd_info *bfd_info, - int multihop, int extra_space, uint8_t use_json, + int multihop, int extra_space, bool use_json, json_object *json_obj); extern void bfd_client_sendmsg(struct zclient *zclient, int command); diff --git a/lib/ferr.c b/lib/ferr.c index 35d0fe4ff4..fb5719d4de 100644 --- a/lib/ferr.c +++ b/lib/ferr.c @@ -148,7 +148,7 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json) snprintf(pbuf, sizeof(pbuf), "\nError %"PRIu32" - %s", ref->code, ref->title); memset(ubuf, '=', strlen(pbuf)); - ubuf[strlen(pbuf) - 1] = '\0'; + ubuf[strlen(pbuf)] = '\0'; vty_out(vty, "%s\n%s\n", pbuf, ubuf); vty_out(vty, "Description:\n%s\n\n", ref->description); diff --git a/lib/json.c b/lib/json.c index 40b6aadaa3..4ea20ba178 100644 --- a/lib/json.c +++ b/lib/json.c @@ -28,15 +28,15 @@ * is the *last* keyword on the line no matter * what. */ -int use_json(const int argc, struct cmd_token *argv[]) +bool use_json(const int argc, struct cmd_token *argv[]) { if (argc == 0) - return 0; + return false; if (argv[argc - 1]->arg && strmatch(argv[argc - 1]->text, "json")) - return 1; + return true; - return 0; + return false; } void json_object_string_add(struct json_object *obj, const char *key, diff --git a/lib/json.h b/lib/json.h index 788d1d6efa..d349162304 100644 --- a/lib/json.h +++ b/lib/json.h @@ -52,7 +52,7 @@ extern int json_object_object_get_ex(struct json_object *obj, const char *key, #include "command.h" -extern int use_json(const int argc, struct cmd_token *argv[]); +extern bool use_json(const int argc, struct cmd_token *argv[]); extern void json_object_string_add(struct json_object *obj, const char *key, const char *s); extern void json_object_int_add(struct json_object *obj, const char *key, @@ -925,7 +925,6 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_IMPORT_ROUTE_REGISTER), DESC_ENTRY(ZEBRA_IMPORT_ROUTE_UNREGISTER), DESC_ENTRY(ZEBRA_IMPORT_CHECK_UPDATE), - DESC_ENTRY(ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD), DESC_ENTRY(ZEBRA_BFD_DEST_REGISTER), DESC_ENTRY(ZEBRA_BFD_DEST_DEREGISTER), DESC_ENTRY(ZEBRA_BFD_DEST_UPDATE), diff --git a/lib/plist.c b/lib/plist.c index 2b666f256f..5746080127 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -396,7 +396,7 @@ static int64_t prefix_new_seq_get(struct prefix_list *plist) newseq = ((maxseq / 5) * 5) + 5; - return newseq; + return (newseq > UINT_MAX) ? UINT_MAX : newseq; } /* Return prefix list entry which has same seq number. */ @@ -1900,7 +1900,7 @@ void prefix_bgp_orf_remove_all(afi_t afi, char *name) /* return prefix count */ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name, - uint8_t use_json) + bool use_json) { struct prefix_list *plist; struct prefix_list_entry *pentry; diff --git a/lib/plist.h b/lib/plist.h index fecbe0e2ce..8a4fa8d3ce 100644 --- a/lib/plist.h +++ b/lib/plist.h @@ -72,6 +72,7 @@ extern struct stream *prefix_bgp_orf_entry(struct stream *, uint8_t, uint8_t); extern int prefix_bgp_orf_set(char *, afi_t, struct orf_prefix *, int, int); extern void prefix_bgp_orf_remove_all(afi_t, char *); -extern int prefix_bgp_show_prefix_list(struct vty *, afi_t, char *, uint8_t); +extern int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name, + bool use_json); #endif /* _QUAGGA_PLIST_H */ diff --git a/lib/routemap.c b/lib/routemap.c index 4125bb53ae..e5613c2081 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -891,6 +891,14 @@ static void vty_show_route_map_entry(struct vty *vty, struct route_map *map) } } +static int sort_route_map(const void **map1, const void **map2) +{ + const struct route_map *m1 = *map1; + const struct route_map *m2 = *map2; + + return strcmp(m1->name, m2->name); +} + static int vty_show_route_map(struct vty *vty, const char *name) { struct route_map *map; @@ -907,9 +915,19 @@ static int vty_show_route_map(struct vty *vty, const char *name) return CMD_SUCCESS; } } else { + + struct list *maplist = list_new(); + struct listnode *ln; + for (map = route_map_master.head; map; map = map->next) - if (!map->deleted) - vty_show_route_map_entry(vty, map); + listnode_add(maplist, map); + + list_sort(maplist, sort_route_map); + + for (ALL_LIST_ELEMENTS_RO(maplist, ln, map)) + vty_show_route_map_entry(vty, map); + + list_delete_and_null(&maplist); } return CMD_SUCCESS; } diff --git a/lib/subdir.am b/lib/subdir.am index 50cfd70a57..ef6c8f8e55 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -6,6 +6,7 @@ lib_libfrr_la_LDFLAGS = -version-info 0:0:0 lib_libfrr_la_LIBADD = @LIBCAP@ lib_libfrr_la_SOURCES = \ + lib/agg_table.c \ lib/bfd.c \ lib/buffer.c \ lib/checksum.c \ @@ -89,6 +90,7 @@ lib/nexthop_group_clippy.c: $(CLIPPY_DEPS) lib/nexthop_group.lo: lib/nexthop_group_clippy.c pkginclude_HEADERS += \ + lib/agg_table.h \ lib/bfd.h \ lib/bitfield.h \ lib/buffer.h \ @@ -291,7 +293,7 @@ if GIT_VERSION # (even if gitversion.h's file timestamp doesn't change, make will think it # did, because of .PHONY...) -.PHONY: lib/gitversion.h.tmp +PHONY_GITVERSION=lib/gitversion.h.tmp .SILENT: lib/gitversion.h lib/gitversion.h.tmp GITH=lib/gitversion.h lib/gitversion.h.tmp: $(top_srcdir)/.git @@ -300,7 +302,8 @@ lib/gitversion.h: lib/gitversion.h.tmp { test -f ${GITH} && diff -s -q ${GITH}.tmp ${GITH}; } || cp ${GITH}.tmp ${GITH} else -.PHONY: lib/gitversion.h +PHONY_GITVERSION=lib/gitversion.h lib/gitversion.h: true endif +.PHONY: $(PHONY_GITVERSION) diff --git a/lib/table.h b/lib/table.h index 8304abe59b..711ace111e 100644 --- a/lib/table.h +++ b/lib/table.h @@ -126,9 +126,6 @@ struct route_table { \ /* Each node of route. */ \ void *info; \ - \ - /* Aggregation. */ \ - void *aggregate; /* Each routing entry. */ diff --git a/lib/zclient.h b/lib/zclient.h index b8ff85e80f..cab734ae5e 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -91,7 +91,6 @@ typedef enum { ZEBRA_IMPORT_ROUTE_REGISTER, ZEBRA_IMPORT_ROUTE_UNREGISTER, ZEBRA_IMPORT_CHECK_UPDATE, - ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD, ZEBRA_BFD_DEST_REGISTER, ZEBRA_BFD_DEST_DEREGISTER, ZEBRA_BFD_DEST_UPDATE, diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c index df41897660..594735a08f 100644 --- a/ospfd/ospf_bfd.c +++ b/ospfd/ospf_bfd.c @@ -312,7 +312,7 @@ void ospf_bfd_write_config(struct vty *vty, struct ospf_if_params *params) * ospf_bfd_show_info - Show BFD info structure */ void ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj, - uint8_t use_json, int param_only) + bool use_json, int param_only) { if (param_only) bfd_show_param(vty, (struct bfd_info *)bfd_info, 1, 0, use_json, @@ -326,7 +326,7 @@ void ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj, * ospf_bfd_interface_show - Show the interface BFD configuration. */ void ospf_bfd_interface_show(struct vty *vty, struct interface *ifp, - json_object *json_interface_sub, uint8_t use_json) + json_object *json_interface_sub, bool use_json) { struct ospf_if_params *params; diff --git a/ospfd/ospf_bfd.h b/ospfd/ospf_bfd.h index 6d7caf4217..74385d3268 100644 --- a/ospfd/ospf_bfd.h +++ b/ospfd/ospf_bfd.h @@ -35,13 +35,13 @@ extern void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, extern void ospf_bfd_interface_show(struct vty *vty, struct interface *ifp, json_object *json_interface_sub, - uint8_t use_json); + bool use_json); extern void ospf_bfd_info_nbr_create(struct ospf_interface *oi, struct ospf_neighbor *nbr); extern void ospf_bfd_show_info(struct vty *vty, void *bfd_info, - json_object *json_obj, uint8_t use_json, + json_object *json_obj, bool use_json, int param_only); extern void ospf_bfd_info_free(void **bfd_info); diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 23dae6b087..62eca156f5 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -2311,7 +2311,7 @@ DEFUN (show_ip_opsf_srdb, int idx = 0; struct in_addr rid; struct sr_node *srn; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); json_object *json = NULL, *json_node_array = NULL; if (!OspfSR.enabled) { diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 39f14a00c3..aa877903fc 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2623,7 +2623,7 @@ const char *ospf_abr_type_descr_str[] = {"Unknown", "Standard (RFC2328)", const char *ospf_shortcut_mode_descr_str[] = {"Default", "Enabled", "Disabled"}; static void show_ip_ospf_area(struct vty *vty, struct ospf_area *area, - json_object *json_areas, uint8_t use_json) + json_object *json_areas, bool use_json) { json_object *json_area = NULL; @@ -3243,7 +3243,7 @@ DEFUN (show_ip_ospf, JSON_STR) { struct ospf *ospf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct listnode *node = NULL; char *vrf_name = NULL; bool all_vrf = FALSE; @@ -3263,11 +3263,15 @@ DEFUN (show_ip_ospf, /* vrf input is provided could be all or specific vrf*/ if (vrf_name) { + bool ospf_output = FALSE; + use_vrf = 1; + if (all_vrf) { for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { if (!ospf->oi_running) continue; + ospf_output = TRUE; ret = show_ip_ospf_common(vty, ospf, json, use_vrf); } @@ -3276,21 +3280,34 @@ DEFUN (show_ip_ospf, json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); - } + } else if (!ospf_output) + vty_out(vty, "%% OSPF instance not found\n"); return ret; } ospf = ospf_lookup_by_inst_name(inst, vrf_name); if ((ospf == NULL) || !ospf->oi_running) { - if (uj) + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + return CMD_SUCCESS; } } else { ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); /* Display default ospf (instance 0) info */ if (ospf == NULL || !ospf->oi_running) { - if (uj) + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + return CMD_SUCCESS; } } @@ -3321,7 +3338,7 @@ DEFUN (show_ip_ospf_instance, int idx_number = 3; struct ospf *ospf; unsigned short instance = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); int ret = CMD_SUCCESS; json_object *json = NULL; @@ -3350,7 +3367,7 @@ DEFUN (show_ip_ospf_instance, static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, struct interface *ifp, json_object *json_interface_sub, - uint8_t use_json) + bool use_json) { int is_up; struct ospf_neighbor *nbr; @@ -3667,7 +3684,7 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf, char *intf_name, uint8_t use_vrf, - json_object *json, uint8_t use_json) + json_object *json, bool use_json) { struct interface *ifp; struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); @@ -3760,7 +3777,7 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf, static void show_ip_ospf_interface_traffic_sub(struct vty *vty, struct ospf_interface *oi, json_object *json_interface_sub, - uint8_t use_json) + bool use_json) { if (use_json) { json_object_int_add(json_interface_sub, "ifIndex", @@ -3798,7 +3815,7 @@ static void show_ip_ospf_interface_traffic_sub(struct vty *vty, /* OSPFv2 Packet Counters */ static int show_ip_ospf_interface_traffic_common( struct vty *vty, struct ospf *ospf, char *intf_name, json_object *json, - int display_once, uint8_t use_vrf, uint8_t use_json) + int display_once, uint8_t use_vrf, bool use_json) { struct vrf *vrf = NULL; struct interface *ifp = NULL; @@ -3916,7 +3933,7 @@ DEFUN (show_ip_ospf_interface, JSON_STR) { struct ospf *ospf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct listnode *node = NULL; char *vrf_name = NULL, *intf_name = NULL; bool all_vrf = FALSE; @@ -3951,14 +3968,21 @@ DEFUN (show_ip_ospf_interface, json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); - } + } else if (!ospf) + vty_out(vty, "%% OSPF instance not found\n"); return ret; } ospf = ospf_lookup_by_inst_name(inst, vrf_name); if (ospf == NULL || !ospf->oi_running) { - if (uj) + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + return CMD_SUCCESS; } ret = show_ip_ospf_interface_common(vty, ospf, intf_name, @@ -3968,8 +3992,14 @@ DEFUN (show_ip_ospf_interface, /* Display default ospf (instance 0) info */ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL || !ospf->oi_running) { - if (uj) + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + return CMD_SUCCESS; } ret = show_ip_ospf_interface_common(vty, ospf, intf_name, @@ -4000,7 +4030,7 @@ DEFUN (show_ip_ospf_instance_interface, int idx_intf = 0; struct ospf *ospf; unsigned short instance = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); char *intf_name = NULL; int ret = CMD_SUCCESS; json_object *json = NULL; @@ -4049,7 +4079,7 @@ DEFUN (show_ip_ospf_interface_traffic, bool all_vrf = FALSE; int inst = 0; int idx_vrf = 0, idx_intf = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); json_object *json = NULL; int ret = CMD_SUCCESS; int display_once = 0; @@ -4125,7 +4155,7 @@ static void show_ip_ospf_neighbour_header(struct vty *vty) static void show_ip_ospf_neighbor_sub(struct vty *vty, struct ospf_interface *oi, - json_object *json, uint8_t use_json) + json_object *json, bool use_json) { struct route_node *rn; struct ospf_neighbor *nbr, *prev_nbr = NULL; @@ -4236,7 +4266,7 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty, } static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf, - json_object *json, uint8_t use_json, + json_object *json, bool use_json, uint8_t use_vrf) { struct ospf_interface *oi; @@ -4298,7 +4328,7 @@ DEFUN (show_ip_ospf_neighbor, JSON_STR) { struct ospf *ospf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct listnode *node = NULL; char *vrf_name = NULL; bool all_vrf = FALSE; @@ -4329,23 +4359,36 @@ DEFUN (show_ip_ospf_neighbor, json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); - } + } else if (!ospf) + vty_out(vty, "OSPF instance not found\n"); return ret; } ospf = ospf_lookup_by_inst_name(inst, vrf_name); if (ospf == NULL || !ospf->oi_running) { - if (uj) + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + return CMD_SUCCESS; } } else { /* Display default ospf (instance 0) info */ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL || !ospf->oi_running) { - if (uj) + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + return CMD_SUCCESS; } } @@ -4381,7 +4424,7 @@ DEFUN (show_ip_ospf_instance_neighbor, int idx_number = 3; struct ospf *ospf; unsigned short instance = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); json_object *json = NULL; int ret = CMD_SUCCESS; @@ -4408,7 +4451,7 @@ DEFUN (show_ip_ospf_instance_neighbor, } static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf, - json_object *json, uint8_t use_json, + json_object *json, bool use_json, uint8_t use_vrf) { struct listnode *node; @@ -4511,7 +4554,7 @@ DEFUN (show_ip_ospf_neighbor_all, JSON_STR) { struct ospf *ospf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct listnode *node = NULL; char *vrf_name = NULL; bool all_vrf = FALSE; @@ -4593,7 +4636,7 @@ DEFUN (show_ip_ospf_instance_neighbor_all, int idx_number = 3; struct ospf *ospf; unsigned short instance = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); json_object *json = NULL; int ret = CMD_SUCCESS; @@ -4621,7 +4664,7 @@ DEFUN (show_ip_ospf_instance_neighbor_all, static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf, int arg_base, struct cmd_token **argv, - uint8_t use_json, uint8_t use_vrf) + bool use_json, uint8_t use_vrf) { struct interface *ifp; struct route_node *rn; @@ -4680,7 +4723,7 @@ DEFUN (show_ip_ospf_neighbor_int, { struct ospf *ospf; int idx_ifname = 4; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct listnode *node = NULL; int ret = CMD_SUCCESS; struct interface *ifp = NULL; @@ -4716,7 +4759,7 @@ DEFUN (show_ip_ospf_instance_neighbor_int, int idx_ifname = 5; struct ospf *ospf; unsigned short instance = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!uj) show_ip_ospf_neighbour_header(vty); @@ -4739,8 +4782,7 @@ DEFUN (show_ip_ospf_instance_neighbor_int, static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty, struct ospf_interface *oi, struct ospf_nbr_nbma *nbr_nbma, - uint8_t use_json, - json_object *json) + bool use_json, json_object *json) { char timebuf[OSPF_TIME_DUMP_SIZE]; json_object *json_sub = NULL; @@ -4820,8 +4862,7 @@ static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty, static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, struct ospf_interface *oi, struct ospf_neighbor *nbr, - json_object *json, - uint8_t use_json) + json_object *json, bool use_json) { char timebuf[OSPF_TIME_DUMP_SIZE]; json_object *json_sub = NULL; @@ -5037,7 +5078,7 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf, int arg_base, struct cmd_token **argv, - uint8_t use_json, uint8_t use_vrf) + bool use_json, uint8_t use_vrf) { struct listnode *node; struct ospf_neighbor *nbr; @@ -5098,7 +5139,7 @@ DEFUN (show_ip_ospf_neighbor_id, JSON_STR) { struct ospf *ospf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct listnode *node = NULL; int ret = CMD_SUCCESS; @@ -5127,7 +5168,7 @@ DEFUN (show_ip_ospf_instance_neighbor_id, int idx_router_id = 5; struct ospf *ospf; unsigned short instance = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); instance = strtoul(argv[idx_number]->arg, NULL, 10); ospf = ospf_lookup_instance(instance); @@ -5143,8 +5184,7 @@ DEFUN (show_ip_ospf_instance_neighbor_id, static int show_ip_ospf_neighbor_detail_common(struct vty *vty, struct ospf *ospf, - json_object *json, - uint8_t use_json, + json_object *json, bool use_json, uint8_t use_vrf) { struct ospf_interface *oi; @@ -5212,7 +5252,7 @@ DEFUN (show_ip_ospf_neighbor_detail, JSON_STR) { struct ospf *ospf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct listnode *node = NULL; char *vrf_name = NULL; bool all_vrf = FALSE; @@ -5292,7 +5332,7 @@ DEFUN (show_ip_ospf_instance_neighbor_detail, int idx_number = 3; struct ospf *ospf; unsigned short instance = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); json_object *json = NULL; int ret = CMD_SUCCESS; @@ -5321,7 +5361,7 @@ DEFUN (show_ip_ospf_instance_neighbor_detail, static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty, struct ospf *ospf, json_object *json, - uint8_t use_json, + bool use_json, uint8_t use_vrf) { struct listnode *node; @@ -5401,7 +5441,7 @@ DEFUN (show_ip_ospf_neighbor_detail_all, JSON_STR) { struct ospf *ospf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct listnode *node = NULL; char *vrf_name = NULL; bool all_vrf = FALSE; @@ -5483,7 +5523,7 @@ DEFUN (show_ip_ospf_instance_neighbor_detail_all, int idx_number = 3; struct ospf *ospf; unsigned short instance = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); json_object *json = NULL; int ret = CMD_SUCCESS; @@ -5513,7 +5553,7 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty, struct ospf *ospf, int arg_base, struct cmd_token **argv, - uint8_t use_json) + bool use_json) { struct ospf_interface *oi; struct interface *ifp; @@ -5581,17 +5621,22 @@ DEFUN (show_ip_ospf_neighbor_int_detail, JSON_STR) { struct ospf *ospf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct listnode *node = NULL; int ret = CMD_SUCCESS; + bool ospf_output = FALSE; for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { if (!ospf->oi_running) continue; + ospf_output = TRUE; ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, 0, argv, uj); } + if (!ospf_output) + vty_out(vty, "%% OSPF instance not found\n"); + return ret; } @@ -5611,7 +5656,7 @@ DEFUN (show_ip_ospf_instance_neighbor_int_detail, int idx_ifname = 5; struct ospf *ospf; unsigned short instance = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); instance = strtoul(argv[idx_number]->arg, NULL, 10); ospf = ospf_lookup_instance(instance); @@ -6296,19 +6341,28 @@ DEFUN (show_ip_ospf_database_max, OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (vrf_name) { + bool ospf_output = FALSE; + use_vrf = 1; + if (all_vrf) { for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { if (!ospf->oi_running) continue; + ospf_output = TRUE; ret = show_ip_ospf_database_common( vty, ospf, idx_vrf ? 2 : 0, argc, argv, use_vrf); } + + if (!ospf_output) + vty_out(vty, "%% OSPF instance not found\n"); } else { ospf = ospf_lookup_by_inst_name(inst, vrf_name); - if (ospf == NULL || !ospf->oi_running) + if (ospf == NULL || !ospf->oi_running) { + vty_out(vty, "%% OSPF instance not found\n"); return CMD_SUCCESS; + } ret = (show_ip_ospf_database_common( vty, ospf, idx_vrf ? 2 : 0, argc, argv, use_vrf)); @@ -6316,8 +6370,11 @@ DEFUN (show_ip_ospf_database_max, } else { /* Display default ospf (instance 0) info */ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); - if (ospf == NULL || !ospf->oi_running) + if (ospf == NULL || !ospf->oi_running) { + vty_out(vty, "%% OSPF instance not found\n"); return CMD_SUCCESS; + } + ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv, use_vrf); } @@ -6377,16 +6434,22 @@ DEFUN (show_ip_ospf_instance_database, } } else { ospf = ospf_lookup_by_inst_name(inst, vrf_name); - if ((ospf == NULL) || !ospf->oi_running) + if ((ospf == NULL) || !ospf->oi_running) { + vty_out(vty, "%% OSPF instance not found\n"); return CMD_SUCCESS; + } + ret = (show_ip_ospf_database_common( vty, ospf, idx ? 2 : 0, argc, argv, use_vrf)); } } else { /* Display default ospf (instance 0) info */ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); - if (ospf == NULL || !ospf->oi_running) + if (ospf == NULL || !ospf->oi_running) { + vty_out(vty, "%% OSPF instance not found\n"); return CMD_SUCCESS; + } + ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv, use_vrf)); } @@ -6415,8 +6478,10 @@ DEFUN (show_ip_ospf_instance_database_max, if (ospf == NULL) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + if (!ospf->oi_running) { + vty_out(vty, "%% OSPF instance not found\n"); return CMD_SUCCESS; + } return show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0); } @@ -6505,8 +6570,11 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, ospf = ospf_lookup_instance(instance); if (ospf == NULL) return CMD_NOT_MY_INSTANCE; - if (!ospf->oi_running) + if (!ospf->oi_running) { + vty_out(vty, "%% OSPF instance not found\n"); return CMD_SUCCESS; + } + return (show_ip_ospf_database_type_adv_router_common( vty, ospf, idx ? 1 : 0, argc, argv, use_vrf)); } @@ -6514,27 +6582,39 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (vrf_name) { + bool ospf_output = FALSE; + use_vrf = 1; + if (all_vrf) { for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { if (!ospf->oi_running) continue; + ospf_output = TRUE; ret = show_ip_ospf_database_type_adv_router_common( vty, ospf, idx ? 1 : 0, argc, argv, use_vrf); } + if (!ospf_output) + vty_out(vty, "%% OSPF instance not found\n"); } else { ospf = ospf_lookup_by_inst_name(inst, vrf_name); - if ((ospf == NULL) || !ospf->oi_running) + if ((ospf == NULL) || !ospf->oi_running) { + vty_out(vty, "%% OSPF instance not found\n"); return CMD_SUCCESS; + } + ret = show_ip_ospf_database_type_adv_router_common( vty, ospf, idx ? 1 : 0, argc, argv, use_vrf); } } else { /* Display default ospf (instance 0) info */ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); - if (ospf == NULL || !ospf->oi_running) + if (ospf == NULL || !ospf->oi_running) { + vty_out(vty, "%% OSPF instance not found\n"); return CMD_SUCCESS; + } + ret = show_ip_ospf_database_type_adv_router_common( vty, ospf, idx ? 1 : 0, argc, argv, use_vrf); } @@ -9271,19 +9351,28 @@ DEFUN (show_ip_ospf_border_routers, OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (vrf_name) { + bool ospf_output = FALSE; + use_vrf = 1; + if (all_vrf) { for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { if (!ospf->oi_running) continue; + ospf_output = TRUE; ret = show_ip_ospf_border_routers_common( vty, ospf, use_vrf); } + + if (!ospf_output) + vty_out(vty, "%% OSPF instance not found\n"); } else { ospf = ospf_lookup_by_inst_name(inst, vrf_name); - if (ospf == NULL || !ospf->oi_running) + if (ospf == NULL || !ospf->oi_running) { + vty_out(vty, "%% OSPF instance not found\n"); return CMD_SUCCESS; + } ret = show_ip_ospf_border_routers_common(vty, ospf, use_vrf); @@ -9291,8 +9380,11 @@ DEFUN (show_ip_ospf_border_routers, } else { /* Display default ospf (instance 0) info */ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); - if (ospf == NULL || !ospf->oi_running) + if (ospf == NULL || !ospf->oi_running) { + vty_out(vty, "%% OSPF instance not found\n"); return CMD_SUCCESS; + } + ret = show_ip_ospf_border_routers_common(vty, ospf, use_vrf); } @@ -9393,7 +9485,7 @@ DEFUN (show_ip_ospf_route, int inst = 0; int idx_vrf = 0; uint8_t use_vrf = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); json_object *json = NULL; if (uj) @@ -9403,11 +9495,15 @@ DEFUN (show_ip_ospf_route, /* vrf input is provided could be all or specific vrf*/ if (vrf_name) { + bool ospf_output = FALSE; + use_vrf = 1; + if (all_vrf) { for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { if (!ospf->oi_running) continue; + ospf_output = TRUE; ret = show_ip_ospf_route_common(vty, ospf, json, use_vrf); } @@ -9417,22 +9513,35 @@ DEFUN (show_ip_ospf_route, vty_out(vty, "%s\n", json_object_to_json_string(json)); json_object_free(json); - } + } else if (!ospf_output) + vty_out(vty, "%% OSPF instance not found\n"); return ret; } ospf = ospf_lookup_by_inst_name(inst, vrf_name); if (ospf == NULL || !ospf->oi_running) { - if (uj) + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + return CMD_SUCCESS; } } else { /* Display default ospf (instance 0) info */ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf == NULL || !ospf->oi_running) { - if (uj) + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + return CMD_SUCCESS; } } @@ -9484,7 +9593,7 @@ DEFUN (show_ip_ospf_vrfs, "Show OSPF VRFs \n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); json_object *json = NULL; json_object *json_vrfs = NULL; struct ospf *ospf = NULL; diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c index f7a217b514..466cc60643 100644 --- a/pimd/pim_bfd.c +++ b/pimd/pim_bfd.c @@ -64,7 +64,7 @@ void pim_bfd_write_config(struct vty *vty, struct interface *ifp) * pim_bfd_show_info - Show BFD info structure */ void pim_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj, - uint8_t use_json, int param_only) + bool use_json, int param_only) { if (param_only) bfd_show_param(vty, (struct bfd_info *)bfd_info, 1, 0, use_json, diff --git a/pimd/pim_bfd.h b/pimd/pim_bfd.h index 83def93b66..962b727f88 100644 --- a/pimd/pim_bfd.h +++ b/pimd/pim_bfd.h @@ -28,7 +28,7 @@ void pim_bfd_init(void); void pim_bfd_write_config(struct vty *vty, struct interface *ifp); void pim_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj, - uint8_t use_json, int param_only); + bool use_json, int param_only); void pim_bfd_if_param_set(struct interface *ifp, uint32_t min_rx, uint32_t min_tx, uint8_t detect_mult, int defaults); int pim_bfd_reg_dereg_all_nbr(struct interface *ifp, int command); diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 611d8d3681..5dc86417cf 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -432,7 +432,7 @@ static void pim_show_membership_helper(struct vty *vty, json_object_object_add(json_iface, ch_grp_str, json_row); } static void pim_show_membership(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct pim_interface *pim_ifp; struct pim_ifchannel *ch; @@ -549,7 +549,7 @@ static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp, } static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct interface *ifp; time_t now; @@ -634,7 +634,7 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty, static void igmp_show_interfaces_single(struct pim_instance *pim, struct vty *vty, const char *ifname, - uint8_t uj) + bool uj) { struct igmp_sock *igmp; struct interface *ifp; @@ -894,7 +894,7 @@ static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty) static void pim_show_interfaces_single(struct pim_instance *pim, struct vty *vty, const char *ifname, - uint8_t uj) + bool uj) { struct in_addr ifaddr; struct interface *ifp; @@ -1295,7 +1295,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim, } static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty, - const char *ifname, uint8_t uj) + const char *ifname, bool uj) { struct interface *ifp; struct igmp_stats rx_stats; @@ -1365,7 +1365,7 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty, } static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct interface *ifp; struct listnode *upnode; @@ -1458,7 +1458,7 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, } static void pim_show_interface_traffic(struct pim_instance *pim, - struct vty *vty, uint8_t uj) + struct vty *vty, bool uj) { struct interface *ifp = NULL; struct pim_interface *pim_ifp = NULL; @@ -1538,7 +1538,7 @@ static void pim_show_interface_traffic(struct pim_instance *pim, static void pim_show_interface_traffic_single(struct pim_instance *pim, struct vty *vty, - const char *ifname, uint8_t uj) + const char *ifname, bool uj) { struct interface *ifp = NULL; struct pim_interface *pim_ifp = NULL; @@ -1627,7 +1627,7 @@ static void pim_show_interface_traffic_single(struct pim_instance *pim, static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp, struct pim_ifchannel *ch, json_object *json, - time_t now, uint8_t uj) + time_t now, bool uj) { char ch_src_str[INET_ADDRSTRLEN]; char ch_grp_str[INET_ADDRSTRLEN]; @@ -1690,7 +1690,7 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp, } } -static void pim_show_join(struct pim_instance *pim, struct vty *vty, uint8_t uj) +static void pim_show_join(struct pim_instance *pim, struct vty *vty, bool uj) { struct pim_interface *pim_ifp; struct pim_ifchannel *ch; @@ -1724,7 +1724,7 @@ static void pim_show_join(struct pim_instance *pim, struct vty *vty, uint8_t uj) } static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty, - const char *neighbor, uint8_t uj) + const char *neighbor, bool uj) { struct listnode *neighnode; struct interface *ifp; @@ -1933,8 +1933,7 @@ static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty, } static void pim_show_state(struct pim_instance *pim, struct vty *vty, - const char *src_or_group, const char *group, - uint8_t uj) + const char *src_or_group, const char *group, bool uj) { struct channel_oil *c_oil; struct listnode *node; @@ -2135,7 +2134,7 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty, } static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *neighnode; struct interface *ifp; @@ -2331,7 +2330,7 @@ static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state, } static void pim_show_upstream(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *upnode; struct pim_upstream *up; @@ -2476,7 +2475,7 @@ static void pim_show_join_desired_helper(struct pim_instance *pim, struct vty *vty, struct pim_interface *pim_ifp, struct pim_ifchannel *ch, - json_object *json, uint8_t uj) + json_object *json, bool uj) { struct pim_upstream *up = ch->upstream; json_object *json_group = NULL; @@ -2532,7 +2531,7 @@ static void pim_show_join_desired_helper(struct pim_instance *pim, } static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct pim_interface *pim_ifp; struct pim_ifchannel *ch; @@ -2568,7 +2567,7 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, } static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *upnode; struct pim_upstream *up; @@ -2701,7 +2700,7 @@ static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty, uptime_mroute_del, (long long)pim->mroute_del_events); } -static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, uint8_t uj) +static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj) { struct listnode *up_node; struct pim_upstream *up; @@ -2821,8 +2820,7 @@ static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty) hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd); } -static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, - uint8_t uj) +static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj) { struct interface *ifp; time_t now; @@ -3373,7 +3371,7 @@ DEFUN (show_ip_igmp_interface, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -3400,7 +3398,7 @@ DEFUN (show_ip_igmp_interface_vrf_all, JSON_STR) { int idx = 2; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -3456,7 +3454,7 @@ DEFUN (show_ip_igmp_join_vrf_all, VRF_CMD_HELP_STR "IGMP static join information\n") { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -3490,7 +3488,7 @@ DEFUN (show_ip_igmp_groups, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -3510,7 +3508,7 @@ DEFUN (show_ip_igmp_groups_vrf_all, IGMP_GROUP_STR JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -3608,7 +3606,7 @@ DEFUN (show_ip_igmp_statistics, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -3715,7 +3713,7 @@ DEFUN (show_ip_pim_interface, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -3742,7 +3740,7 @@ DEFUN (show_ip_pim_interface_vrf_all, JSON_STR) { int idx = 6; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -3781,7 +3779,7 @@ DEFUN (show_ip_pim_join, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -3801,7 +3799,7 @@ DEFUN (show_ip_pim_join_vrf_all, "PIM interface join information\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -3835,7 +3833,7 @@ DEFUN (show_ip_pim_local_membership, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -3859,7 +3857,7 @@ DEFUN (show_ip_pim_neighbor, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -3886,7 +3884,7 @@ DEFUN (show_ip_pim_neighbor_vrf_all, JSON_STR) { int idx = 2; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -3949,7 +3947,7 @@ DEFUN (show_ip_pim_state, const char *group = NULL; int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -3983,7 +3981,7 @@ DEFUN (show_ip_pim_state_vrf_all, const char *src_or_group = NULL; const char *group = NULL; int idx = 2; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -4026,7 +4024,7 @@ DEFUN (show_ip_pim_upstream, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -4046,7 +4044,7 @@ DEFUN (show_ip_pim_upstream_vrf_all, "PIM upstream information\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -4078,7 +4076,7 @@ DEFUN (show_ip_pim_upstream_join_desired, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -4100,7 +4098,7 @@ DEFUN (show_ip_pim_upstream_rpf, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -4122,7 +4120,7 @@ DEFUN (show_ip_pim_rp, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -4142,7 +4140,7 @@ DEFUN (show_ip_pim_rp_vrf_all, "PIM RP information\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -4176,7 +4174,7 @@ DEFUN (show_ip_pim_rpf, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -4196,7 +4194,7 @@ DEFUN (show_ip_pim_rpf_vrf_all, "PIM cached source rpf information\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -4349,7 +4347,7 @@ DEFUN (show_ip_pim_interface_traffic, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -4473,7 +4471,7 @@ DEFUN (show_ip_multicast_vrf_all, VRF_CMD_HELP_STR "Multicast global information\n") { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -4496,7 +4494,7 @@ DEFUN (show_ip_multicast_vrf_all, } static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill, - uint8_t uj) + bool uj) { struct listnode *node; struct channel_oil *c_oil; @@ -4830,7 +4828,7 @@ DEFUN (show_ip_mroute, "Fill in Assumed data\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); bool fill = false; int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); @@ -4855,7 +4853,7 @@ DEFUN (show_ip_mroute_vrf_all, "Fill in Assumed data\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); int idx = 4; struct vrf *vrf; bool first = true; @@ -4963,7 +4961,7 @@ DEFUN (show_ip_mroute_count_vrf_all, VRF_CMD_HELP_STR "Route and packet count data\n") { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -5549,7 +5547,7 @@ DEFUN (no_ip_pim_ssm_prefix_list_name, } static void ip_pim_ssm_show_group_range(struct pim_instance *pim, - struct vty *vty, uint8_t uj) + struct vty *vty, bool uj) { struct pim_ssm *ssm = pim->ssm_info; const char *range_str = @@ -5578,7 +5576,7 @@ DEFUN (show_ip_pim_ssm_range, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -5589,7 +5587,7 @@ DEFUN (show_ip_pim_ssm_range, } static void ip_pim_ssm_show_group_type(struct pim_instance *pim, - struct vty *vty, uint8_t uj, + struct vty *vty, bool uj, const char *group) { struct in_addr group_addr; @@ -5631,7 +5629,7 @@ DEFUN (show_ip_pim_group_type, { int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!vrf) return CMD_WARNING; @@ -7908,7 +7906,7 @@ static void print_empty_json_obj(struct vty *vty) } static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *mbrnode; struct pim_msdp_mg_mbr *mbr; @@ -7985,7 +7983,7 @@ DEFUN (show_ip_msdp_mesh_group, "MSDP mesh-group information\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); @@ -8007,7 +8005,7 @@ DEFUN (show_ip_msdp_mesh_group_vrf_all, "MSDP mesh-group information\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -8030,7 +8028,7 @@ DEFUN (show_ip_msdp_mesh_group_vrf_all, } static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *mpnode; struct pim_msdp_peer *mp; @@ -8084,7 +8082,7 @@ static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty, } static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty, - const char *peer, uint8_t uj) + const char *peer, bool uj) { struct listnode *mpnode; struct pim_msdp_peer *mp; @@ -8200,7 +8198,7 @@ DEFUN (show_ip_msdp_peer_detail, "peer ip address\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); @@ -8235,7 +8233,7 @@ DEFUN (show_ip_msdp_peer_detail_vrf_all, JSON_STR) { int idx = 2; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -8262,8 +8260,7 @@ DEFUN (show_ip_msdp_peer_detail_vrf_all, return CMD_SUCCESS; } -static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, - uint8_t uj) +static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj) { struct listnode *sanode; struct pim_msdp_sa *sa; @@ -8340,7 +8337,7 @@ static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa, const char *src_str, const char *grp_str, struct vty *vty, - uint8_t uj, json_object *json) + bool uj, json_object *json) { char rp_str[INET_ADDRSTRLEN]; char peer_str[INET_ADDRSTRLEN]; @@ -8404,7 +8401,7 @@ static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa, } static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty, - uint8_t uj) + bool uj) { struct listnode *sanode; struct pim_msdp_sa *sa; @@ -8441,7 +8438,7 @@ DEFUN (show_ip_msdp_sa_detail, "Detailed output\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); int idx = 2; struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); @@ -8464,7 +8461,7 @@ DEFUN (show_ip_msdp_sa_detail_vrf_all, "Detailed output\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; @@ -8487,7 +8484,7 @@ DEFUN (show_ip_msdp_sa_detail_vrf_all, } static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty, - const char *addr, uint8_t uj) + const char *addr, bool uj) { struct listnode *sanode; struct pim_msdp_sa *sa; @@ -8516,7 +8513,7 @@ static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty, } static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty, - const char *src, const char *grp, uint8_t uj) + const char *src, const char *grp, bool uj) { struct listnode *sanode; struct pim_msdp_sa *sa; @@ -8556,7 +8553,7 @@ DEFUN (show_ip_msdp_sa_sg, "group ip\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; int idx = 2; @@ -8593,7 +8590,7 @@ DEFUN (show_ip_msdp_sa_sg_vrf_all, "group ip\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); struct vrf *vrf; bool first = true; int idx = 2; diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 3db5015e73..031e527eb3 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -951,8 +951,7 @@ int pim_rp_check_is_my_ip_address(struct pim_instance *pim, return 0; } -void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, - uint8_t uj) +void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) { struct rp_info *rp_info; struct rp_info *prev_rp_info = NULL; diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h index e0631b27be..672a696319 100644 --- a/pimd/pim_rp.h +++ b/pimd/pim_rp.h @@ -68,7 +68,7 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group); #define RP(P, G) pim_rp_g ((P), (G)) void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, - uint8_t uj); + bool uj); void pim_resolve_rp_nh(struct pim_instance *pim); int pim_rp_list_cmp(void *v1, void *v2); #endif diff --git a/python/clidef.py b/python/clidef.py index 2e55909647..4134f4c94e 100644 --- a/python/clidef.py +++ b/python/clidef.py @@ -277,4 +277,4 @@ if __name__ == '__main__': process_file(args.cfile, ofd, dumpfd, args.all_defun) if args.o is not None: - clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__)]) + clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__), sys.executable]) diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index ef324b001a..d7d3d245d6 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -31,7 +31,7 @@ #include "stream.h" #include "zclient.h" #include "command.h" -#include "table.h" +#include "agg_table.h" #include "thread.h" #include "privs.h" #include "vrf.h" @@ -159,14 +159,15 @@ static int ripng_if_ipv6_lladdress_check(struct interface *ifp) static int ripng_if_down(struct interface *ifp) { - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo; struct ripng_interface *ri; struct list *list = NULL; struct listnode *listnode = NULL, *nextnode = NULL; if (ripng) - for (rp = route_top(ripng->table); rp; rp = route_next(rp)) + for (rp = agg_route_top(ripng->table); rp; + rp = agg_route_next(rp)) if ((list = rp->info) != NULL) for (ALL_LIST_ELEMENTS(list, listnode, nextnode, rinfo)) @@ -479,7 +480,7 @@ int ripng_interface_address_delete(int command, struct zclient *zclient, vector ripng_enable_if; /* RIPng enable network table. */ -struct route_table *ripng_enable_network; +struct agg_table *ripng_enable_network; /* Lookup RIPng enable network. */ /* Check wether the interface has at least a connected prefix that @@ -492,7 +493,7 @@ static int ripng_enable_network_lookup_if(struct interface *ifp) for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) { struct prefix *p; - struct route_node *n; + struct agg_node *n; p = connected->address; @@ -501,10 +502,10 @@ static int ripng_enable_network_lookup_if(struct interface *ifp) address.prefix = p->u.prefix6; address.prefixlen = IPV6_MAX_BITLEN; - n = route_node_match(ripng_enable_network, - (struct prefix *)&address); + n = agg_node_match(ripng_enable_network, + (struct prefix *)&address); if (n) { - route_unlock_node(n); + agg_unlock_node(n); return 1; } } @@ -521,7 +522,7 @@ static int ripng_enable_network_lookup2(struct connected *connected) p = connected->address; if (p->family == AF_INET6) { - struct route_node *node; + struct agg_node *node; address.family = p->family; address.prefix = p->u.prefix6; @@ -529,11 +530,11 @@ static int ripng_enable_network_lookup2(struct connected *connected) /* LPM on p->family, p->u.prefix6/IPV6_MAX_BITLEN within * ripng_enable_network */ - node = route_node_match(ripng_enable_network, - (struct prefix *)&address); + node = agg_node_match(ripng_enable_network, + (struct prefix *)&address); if (node) { - route_unlock_node(node); + agg_unlock_node(node); return 1; } } @@ -544,12 +545,12 @@ static int ripng_enable_network_lookup2(struct connected *connected) /* Add RIPng enable network. */ static int ripng_enable_network_add(struct prefix *p) { - struct route_node *node; + struct agg_node *node; - node = route_node_get(ripng_enable_network, p); + node = agg_node_get(ripng_enable_network, p); if (node->info) { - route_unlock_node(node); + agg_unlock_node(node); return -1; } else node->info = (void *)1; @@ -563,17 +564,17 @@ static int ripng_enable_network_add(struct prefix *p) /* Delete RIPng enable network. */ static int ripng_enable_network_delete(struct prefix *p) { - struct route_node *node; + struct agg_node *node; - node = route_node_lookup(ripng_enable_network, p); + node = agg_node_lookup(ripng_enable_network, p); if (node) { node->info = NULL; /* Unlock info lock. */ - route_unlock_node(node); + agg_unlock_node(node); /* Unlock lookup lock. */ - route_unlock_node(node); + agg_unlock_node(node); return 1; } @@ -771,13 +772,14 @@ void ripng_clean_network() { unsigned int i; char *str; - struct route_node *rn; + struct agg_node *rn; /* ripng_enable_network */ - for (rn = route_top(ripng_enable_network); rn; rn = route_next(rn)) + for (rn = agg_route_top(ripng_enable_network); rn; + rn = agg_route_next(rn)) if (rn->info) { rn->info = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); } /* ripng_enable_if */ @@ -877,12 +879,12 @@ int ripng_network_write(struct vty *vty, int config_mode) { unsigned int i; const char *ifname; - struct route_node *node; + struct agg_node *node; char buf[BUFSIZ]; /* Write enable network. */ - for (node = route_top(ripng_enable_network); node; - node = route_next(node)) + for (node = agg_route_top(ripng_enable_network); node; + node = agg_route_next(node)) if (node->info) { struct prefix *p = &node->p; vty_out(vty, "%s%s/%d\n", @@ -1124,7 +1126,7 @@ void ripng_if_init() hook_register_prio(if_del, 0, ripng_if_delete_hook); /* RIPng enable network init. */ - ripng_enable_network = route_table_init(); + ripng_enable_network = agg_table_init(); /* RIPng enable interface init. */ ripng_enable_if = vector_init(1); diff --git a/ripngd/ripng_route.c b/ripngd/ripng_route.c index 83cb59c8b8..f66a0b9527 100644 --- a/ripngd/ripng_route.c +++ b/ripngd/ripng_route.c @@ -22,7 +22,7 @@ #include <zebra.h> #include "prefix.h" -#include "table.h" +#include "agg_table.h" #include "memory.h" #include "if.h" #include "vty.h" @@ -44,13 +44,12 @@ void ripng_aggregate_free(struct ripng_aggregate *aggregate) } /* Aggregate count increment check. */ -void ripng_aggregate_increment(struct route_node *child, - struct ripng_info *rinfo) +void ripng_aggregate_increment(struct agg_node *child, struct ripng_info *rinfo) { - struct route_node *np; + struct agg_node *np; struct ripng_aggregate *aggregate; - for (np = child; np; np = np->parent) + for (np = child; np; np = agg_node_parent(np)) if ((aggregate = np->aggregate) != NULL) { aggregate->count++; rinfo->suppress++; @@ -58,13 +57,12 @@ void ripng_aggregate_increment(struct route_node *child, } /* Aggregate count decrement check. */ -void ripng_aggregate_decrement(struct route_node *child, - struct ripng_info *rinfo) +void ripng_aggregate_decrement(struct agg_node *child, struct ripng_info *rinfo) { - struct route_node *np; + struct agg_node *np; struct ripng_aggregate *aggregate; - for (np = child; np; np = np->parent) + for (np = child; np; np = agg_node_parent(np)) if ((aggregate = np->aggregate) != NULL) { aggregate->count--; rinfo->suppress--; @@ -72,14 +70,14 @@ void ripng_aggregate_decrement(struct route_node *child, } /* Aggregate count decrement check for a list. */ -void ripng_aggregate_decrement_list(struct route_node *child, struct list *list) +void ripng_aggregate_decrement_list(struct agg_node *child, struct list *list) { - struct route_node *np; + struct agg_node *np; struct ripng_aggregate *aggregate; struct ripng_info *rinfo = NULL; struct listnode *node = NULL; - for (np = child; np; np = np->parent) + for (np = child; np; np = agg_node_parent(np)) if ((aggregate = np->aggregate) != NULL) aggregate->count -= listcount(list); @@ -90,8 +88,8 @@ void ripng_aggregate_decrement_list(struct route_node *child, struct list *list) /* RIPng routes treatment. */ int ripng_aggregate_add(struct prefix *p) { - struct route_node *top; - struct route_node *rp; + struct agg_node *top; + struct agg_node *rp; struct ripng_info *rinfo; struct ripng_aggregate *aggregate; struct ripng_aggregate *sub; @@ -99,7 +97,7 @@ int ripng_aggregate_add(struct prefix *p) struct listnode *node = NULL; /* Get top node for aggregation. */ - top = route_node_get(ripng->table, p); + top = agg_node_get(ripng->table, p); /* Allocate new aggregate. */ aggregate = ripng_aggregate_new(); @@ -108,7 +106,7 @@ int ripng_aggregate_add(struct prefix *p) top->aggregate = aggregate; /* Suppress routes match to the aggregate. */ - for (rp = route_lock_node(top); rp; rp = route_next_until(rp, top)) { + for (rp = agg_lock_node(top); rp; rp = agg_route_next_until(rp, top)) { /* Suppress normal route. */ if ((list = rp->info) != NULL) for (ALL_LIST_ELEMENTS_RO(list, node, rinfo)) { @@ -128,8 +126,8 @@ int ripng_aggregate_add(struct prefix *p) /* Delete RIPng static route. */ int ripng_aggregate_delete(struct prefix *p) { - struct route_node *top; - struct route_node *rp; + struct agg_node *top; + struct agg_node *rp; struct ripng_info *rinfo; struct ripng_aggregate *aggregate; struct ripng_aggregate *sub; @@ -137,13 +135,13 @@ int ripng_aggregate_delete(struct prefix *p) struct listnode *node = NULL; /* Get top node for aggregation. */ - top = route_node_get(ripng->table, p); + top = agg_node_get(ripng->table, p); /* Allocate new aggregate. */ aggregate = top->aggregate; /* Suppress routes match to the aggregate. */ - for (rp = route_lock_node(top); rp; rp = route_next_until(rp, top)) { + for (rp = agg_lock_node(top); rp; rp = agg_route_next_until(rp, top)) { /* Suppress normal route. */ if ((list = rp->info) != NULL) for (ALL_LIST_ELEMENTS_RO(list, node, rinfo)) { @@ -160,8 +158,8 @@ int ripng_aggregate_delete(struct prefix *p) top->aggregate = NULL; ripng_aggregate_free(aggregate); - route_unlock_node(top); - route_unlock_node(top); + agg_unlock_node(top); + agg_unlock_node(top); return 0; } diff --git a/ripngd/ripng_route.h b/ripngd/ripng_route.h index dc7d422d1e..e402f4a66c 100644 --- a/ripngd/ripng_route.h +++ b/ripngd/ripng_route.h @@ -42,11 +42,11 @@ struct ripng_aggregate { uint16_t tag_out; }; -extern void ripng_aggregate_increment(struct route_node *rp, +extern void ripng_aggregate_increment(struct agg_node *rp, struct ripng_info *rinfo); -extern void ripng_aggregate_decrement(struct route_node *rp, +extern void ripng_aggregate_decrement(struct agg_node *rp, struct ripng_info *rinfo); -extern void ripng_aggregate_decrement_list(struct route_node *rp, +extern void ripng_aggregate_decrement_list(struct agg_node *rp, struct list *list); extern int ripng_aggregate_add(struct prefix *p); extern int ripng_aggregate_delete(struct prefix *p); diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index 6830e0e926..a8cc9ee128 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -23,7 +23,7 @@ #include "command.h" #include "prefix.h" -#include "table.h" +#include "agg_table.h" #include "stream.h" #include "memory.h" #include "routemap.h" @@ -37,7 +37,7 @@ struct zclient *zclient = NULL; /* Send ECMP routes to zebra. */ -static void ripng_zebra_ipv6_send(struct route_node *rp, uint8_t cmd) +static void ripng_zebra_ipv6_send(struct agg_node *rp, uint8_t cmd) { struct list *list = (struct list *)rp->info; struct zapi_route api; @@ -100,13 +100,13 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, uint8_t cmd) } /* Add/update ECMP routes to zebra. */ -void ripng_zebra_ipv6_add(struct route_node *rp) +void ripng_zebra_ipv6_add(struct agg_node *rp) { ripng_zebra_ipv6_send(rp, ZEBRA_ROUTE_ADD); } /* Delete ECMP routes from zebra. */ -void ripng_zebra_ipv6_delete(struct route_node *rp) +void ripng_zebra_ipv6_delete(struct agg_node *rp) { ripng_zebra_ipv6_send(rp, ZEBRA_ROUTE_DELETE); } diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 934a87b075..d1341d67b7 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -27,7 +27,7 @@ #include "memory.h" #include "if.h" #include "stream.h" -#include "table.h" +#include "agg_table.h" #include "command.h" #include "sockopt.h" #include "distribute.h" @@ -394,7 +394,7 @@ static int ripng_lladdr_check(struct interface *ifp, struct in6_addr *addr) static int ripng_garbage_collect(struct thread *t) { struct ripng_info *rinfo; - struct route_node *rp; + struct agg_node *rp; rinfo = THREAD_ARG(t); rinfo->t_garbage_collect = NULL; @@ -409,7 +409,7 @@ static int ripng_garbage_collect(struct thread *t) listnode_delete(rp->info, rinfo); if (list_isempty((struct list *)rp->info)) { list_delete_and_null((struct list **)&rp->info); - route_unlock_node(rp); + agg_unlock_node(rp); } /* Free RIPng routing information. */ @@ -426,7 +426,7 @@ static void ripng_timeout_update(struct ripng_info *rinfo); */ struct ripng_info *ripng_ecmp_add(struct ripng_info *rinfo_new) { - struct route_node *rp = rinfo_new->rp; + struct agg_node *rp = rinfo_new->rp; struct ripng_info *rinfo = NULL; struct list *list = NULL; @@ -465,7 +465,7 @@ struct ripng_info *ripng_ecmp_add(struct ripng_info *rinfo_new) */ struct ripng_info *ripng_ecmp_replace(struct ripng_info *rinfo_new) { - struct route_node *rp = rinfo_new->rp; + struct agg_node *rp = rinfo_new->rp; struct list *list = (struct list *)rp->info; struct ripng_info *rinfo = NULL, *tmp_rinfo = NULL; struct listnode *node = NULL, *nextnode = NULL; @@ -522,7 +522,7 @@ struct ripng_info *ripng_ecmp_replace(struct ripng_info *rinfo_new) */ struct ripng_info *ripng_ecmp_delete(struct ripng_info *rinfo) { - struct route_node *rp = rinfo->rp; + struct agg_node *rp = rinfo->rp; struct list *list = (struct list *)rp->info; RIPNG_TIMER_OFF(rinfo->t_timeout); @@ -664,7 +664,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from, { int ret; struct prefix_ipv6 p; - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo = NULL, newinfo; struct ripng_interface *ri; struct in6_addr *nexthop; @@ -773,7 +773,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from, nexthop = &from->sin6_addr; /* Lookup RIPng routing table. */ - rp = route_node_get(ripng->table, (struct prefix *)&p); + rp = agg_node_get(ripng->table, (struct prefix *)&p); newinfo.rp = rp; newinfo.nexthop = *nexthop; @@ -798,7 +798,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from, if (rte->metric > rinfo->metric) { /* New route has a greater metric. * Discard it. */ - route_unlock_node(rp); + agg_unlock_node(rp); return; } @@ -821,7 +821,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from, /* Redistributed route check. */ if (rinfo->type != ZEBRA_ROUTE_RIPNG && rinfo->metric != RIPNG_METRIC_INFINITY) { - route_unlock_node(rp); + agg_unlock_node(rp); return; } @@ -830,7 +830,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from, && ((rinfo->sub_type == RIPNG_ROUTE_STATIC) || (rinfo->sub_type == RIPNG_ROUTE_DEFAULT)) && rinfo->metric != RIPNG_METRIC_INFINITY) { - route_unlock_node(rp); + agg_unlock_node(rp); return; } } @@ -844,7 +844,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from, if (rte->metric != RIPNG_METRIC_INFINITY) ripng_ecmp_add(&newinfo); else - route_unlock_node(rp); + agg_unlock_node(rp); } else { /* If there is an existing route, compare the next hop address to the address of the router from which the datagram came. @@ -890,7 +890,7 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from, ripng_timeout_update(rinfo); /* Unlock tempolary lock of the route. */ - route_unlock_node(rp); + agg_unlock_node(rp); } } @@ -899,7 +899,7 @@ void ripng_redistribute_add(int type, int sub_type, struct prefix_ipv6 *p, ifindex_t ifindex, struct in6_addr *nexthop, route_tag_t tag) { - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo = NULL, newinfo; struct list *list = NULL; @@ -909,7 +909,7 @@ void ripng_redistribute_add(int type, int sub_type, struct prefix_ipv6 *p, if (IN6_IS_ADDR_LOOPBACK(&p->prefix)) return; - rp = route_node_get(ripng->table, (struct prefix *)p); + rp = agg_node_get(ripng->table, (struct prefix *)p); memset(&newinfo, 0, sizeof(struct ripng_info)); newinfo.type = type; @@ -928,7 +928,7 @@ void ripng_redistribute_add(int type, int sub_type, struct prefix_ipv6 *p, if (rinfo->type == ZEBRA_ROUTE_CONNECT && rinfo->sub_type == RIPNG_ROUTE_INTERFACE && rinfo->metric != RIPNG_METRIC_INFINITY) { - route_unlock_node(rp); + agg_unlock_node(rp); return; } @@ -941,13 +941,13 @@ void ripng_redistribute_add(int type, int sub_type, struct prefix_ipv6 *p, if (type != ZEBRA_ROUTE_RIPNG || ((sub_type != RIPNG_ROUTE_STATIC) && (sub_type != RIPNG_ROUTE_DEFAULT))) { - route_unlock_node(rp); + agg_unlock_node(rp); return; } } ripng_ecmp_replace(&newinfo); - route_unlock_node(rp); + agg_unlock_node(rp); } else ripng_ecmp_add(&newinfo); @@ -972,7 +972,7 @@ void ripng_redistribute_add(int type, int sub_type, struct prefix_ipv6 *p, void ripng_redistribute_delete(int type, int sub_type, struct prefix_ipv6 *p, ifindex_t ifindex) { - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo; if (IN6_IS_ADDR_LINKLOCAL(&p->prefix)) @@ -980,7 +980,7 @@ void ripng_redistribute_delete(int type, int sub_type, struct prefix_ipv6 *p, if (IN6_IS_ADDR_LOOPBACK(&p->prefix)) return; - rp = route_node_lookup(ripng->table, (struct prefix *)p); + rp = agg_node_lookup(ripng->table, (struct prefix *)p); if (rp) { struct list *list = rp->info; @@ -1014,21 +1014,21 @@ void ripng_redistribute_delete(int type, int sub_type, struct prefix_ipv6 *p, ripng_event(RIPNG_TRIGGERED_UPDATE, 0); } } - route_unlock_node(rp); + agg_unlock_node(rp); } } /* Withdraw redistributed route. */ void ripng_redistribute_withdraw(int type) { - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo = NULL; struct list *list = NULL; if (!ripng) return; - for (rp = route_top(ripng->table); rp; rp = route_next(rp)) + for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) if ((list = rp->info) != NULL) { rinfo = listgetdata(listhead(list)); if ((rinfo->type == type) @@ -1199,7 +1199,7 @@ static void ripng_request_process(struct ripng_packet *packet, int size, caddr_t lim; struct rte *rte; struct prefix_ipv6 p; - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo; struct ripng_interface *ri; @@ -1255,14 +1255,13 @@ static void ripng_request_process(struct ripng_packet *packet, int size, p.prefixlen = rte->prefixlen; apply_mask_ipv6(&p); - rp = route_node_lookup(ripng->table, - (struct prefix *)&p); + rp = agg_node_lookup(ripng->table, (struct prefix *)&p); if (rp) { rinfo = listgetdata( listhead((struct list *)rp->info)); rte->metric = rinfo->metric; - route_unlock_node(rp); + agg_unlock_node(rp); } else rte->metric = RIPNG_METRIC_INFINITY; } @@ -1361,12 +1360,12 @@ static int ripng_read(struct thread *thread) /* Walk down the RIPng routing table then clear changed flag. */ static void ripng_clear_changed_flag(void) { - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo = NULL; struct list *list = NULL; struct listnode *listnode = NULL; - for (rp = route_top(ripng->table); rp; rp = route_next(rp)) + for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) if ((list = rp->info) != NULL) for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { UNSET_FLAG(rinfo->flags, RIPNG_RTF_CHANGED); @@ -1535,7 +1534,7 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to, int route_type) { int ret; - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo; struct ripng_interface *ri; struct ripng_aggregate *aggregate; @@ -1558,7 +1557,7 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to, ripng_rte_list = ripng_rte_new(); - for (rp = route_top(ripng->table); rp; rp = route_next(rp)) { + for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) { if ((list = rp->info) != NULL && (rinfo = listgetdata(listhead(list))) != NULL && rinfo->suppress == 0) { @@ -1807,9 +1806,9 @@ static int ripng_create(void) ripng->obuf = stream_new(RIPNG_MAX_PACKET_SIZE); /* Initialize RIPng routig table. */ - ripng->table = route_table_init(); - ripng->route = route_table_init(); - ripng->aggregate = route_table_init(); + ripng->table = agg_table_init(); + ripng->route = agg_table_init(); + ripng->aggregate = agg_table_init(); /* Make socket. */ ripng->sock = ripng_make_socket(); @@ -1952,7 +1951,7 @@ DEFUN (show_ipv6_ripng, IPV6_STR "Show RIPng routes\n") { - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo; struct ripng_aggregate *aggregate; struct prefix_ipv6 *p; @@ -1971,7 +1970,7 @@ DEFUN (show_ipv6_ripng, " (i) - interface, (a/S) - aggregated/Suppressed\n\n" " Network Next Hop Via Metric Tag Time\n"); - for (rp = route_top(ripng->table); rp; rp = route_next(rp)) { + for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) { if ((aggregate = rp->aggregate) != NULL) { p = (struct prefix_ipv6 *)&rp->p; @@ -2125,13 +2124,13 @@ DEFUN (clear_ipv6_rip, IPV6_STR "Clear IPv6 RIP database\n") { - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo; struct list *list; struct listnode *listnode; /* Clear received RIPng routes */ - for (rp = route_top(ripng->table); rp; rp = route_next(rp)) { + for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) { list = rp->info; if (list == NULL) continue; @@ -2155,7 +2154,7 @@ DEFUN (clear_ipv6_rip, if (list_isempty(list)) { list_delete_and_null(&list); rp->info = NULL; - route_unlock_node(rp); + agg_unlock_node(rp); } } @@ -2206,7 +2205,7 @@ DEFUN (ripng_route, int idx_ipv6addr = 1; int ret; struct prefix_ipv6 p; - struct route_node *rp; + struct agg_node *rp; ret = str2prefix_ipv6(argv[idx_ipv6addr]->arg, (struct prefix_ipv6 *)&p); @@ -2216,10 +2215,10 @@ DEFUN (ripng_route, } apply_mask_ipv6(&p); - rp = route_node_get(ripng->route, (struct prefix *)&p); + rp = agg_node_get(ripng->route, (struct prefix *)&p); if (rp->info) { vty_out(vty, "There is already same static route.\n"); - route_unlock_node(rp); + agg_unlock_node(rp); return CMD_WARNING; } rp->info = (void *)1; @@ -2240,7 +2239,7 @@ DEFUN (no_ripng_route, int idx_ipv6addr = 2; int ret; struct prefix_ipv6 p; - struct route_node *rp; + struct agg_node *rp; ret = str2prefix_ipv6(argv[idx_ipv6addr]->arg, (struct prefix_ipv6 *)&p); @@ -2250,17 +2249,17 @@ DEFUN (no_ripng_route, } apply_mask_ipv6(&p); - rp = route_node_lookup(ripng->route, (struct prefix *)&p); + rp = agg_node_lookup(ripng->route, (struct prefix *)&p); if (!rp) { vty_out(vty, "Can't find static route.\n"); return CMD_WARNING_CONFIG_FAILED; } ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0); - route_unlock_node(rp); + agg_unlock_node(rp); rp->info = NULL; - route_unlock_node(rp); + agg_unlock_node(rp); return CMD_SUCCESS; } @@ -2274,7 +2273,7 @@ DEFUN (ripng_aggregate_address, int idx_ipv6_prefixlen = 1; int ret; struct prefix p; - struct route_node *node; + struct agg_node *node; ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg, (struct prefix_ipv6 *)&p); @@ -2284,10 +2283,10 @@ DEFUN (ripng_aggregate_address, } /* Check aggregate alredy exist or not. */ - node = route_node_get(ripng->aggregate, &p); + node = agg_node_get(ripng->aggregate, &p); if (node->info) { vty_out(vty, "There is already same aggregate route.\n"); - route_unlock_node(node); + agg_unlock_node(node); return CMD_WARNING; } node->info = (void *)1; @@ -2307,7 +2306,7 @@ DEFUN (no_ripng_aggregate_address, int idx_ipv6_prefixlen = 2; int ret; struct prefix p; - struct route_node *rn; + struct agg_node *rn; ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg, (struct prefix_ipv6 *)&p); @@ -2316,14 +2315,14 @@ DEFUN (no_ripng_aggregate_address, return CMD_WARNING_CONFIG_FAILED; } - rn = route_node_lookup(ripng->aggregate, &p); + rn = agg_node_lookup(ripng->aggregate, &p); if (!rn) { vty_out(vty, "Can't find aggregate route.\n"); return CMD_WARNING_CONFIG_FAILED; } - route_unlock_node(rn); + agg_unlock_node(rn); rn->info = NULL; - route_unlock_node(rn); + agg_unlock_node(rn); ripng_aggregate_delete(&p); @@ -2582,7 +2581,7 @@ DEFUN (no_ripng_default_information_originate, /* Update ECMP routes to zebra when ECMP is disabled. */ static void ripng_ecmp_disable(void) { - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo, *tmp_rinfo; struct list *list; struct listnode *node, *nextnode; @@ -2590,7 +2589,7 @@ static void ripng_ecmp_disable(void) if (!ripng) return; - for (rp = route_top(ripng->table); rp; rp = route_next(rp)) + for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) if ((list = rp->info) != NULL && listcount(list) > 1) { rinfo = listgetdata(listhead(list)); if (!ripng_route_rte(rinfo)) @@ -2655,7 +2654,7 @@ static int ripng_config_write(struct vty *vty) int ripng_network_write(struct vty *, int); void ripng_redistribute_write(struct vty *, int); int write = 0; - struct route_node *rp; + struct agg_node *rp; if (ripng) { @@ -2678,7 +2677,8 @@ static int ripng_config_write(struct vty *vty) config_write_ripng_offset_list(vty); /* RIPng aggregate routes. */ - for (rp = route_top(ripng->aggregate); rp; rp = route_next(rp)) + for (rp = agg_route_top(ripng->aggregate); rp; + rp = agg_route_next(rp)) if (rp->info != NULL) vty_out(vty, " aggregate-address %s/%d\n", inet6_ntoa(rp->p.u.prefix6), @@ -2689,7 +2689,8 @@ static int ripng_config_write(struct vty *vty) vty_out(vty, " allow-ecmp\n"); /* RIPng static routes. */ - for (rp = route_top(ripng->route); rp; rp = route_next(rp)) + for (rp = agg_route_top(ripng->route); rp; + rp = agg_route_next(rp)) if (rp->info != NULL) vty_out(vty, " route %s/%d\n", inet6_ntoa(rp->p.u.prefix6), @@ -2811,7 +2812,7 @@ static void ripng_distribute_update_all_wrapper(struct access_list *notused) void ripng_clean() { int i; - struct route_node *rp; + struct agg_node *rp; struct ripng_info *rinfo; struct ripng_aggregate *aggregate; struct list *list = NULL; @@ -2819,7 +2820,8 @@ void ripng_clean() if (ripng) { /* Clear RIPng routes */ - for (rp = route_top(ripng->table); rp; rp = route_next(rp)) { + for (rp = agg_route_top(ripng->table); rp; + rp = agg_route_next(rp)) { if ((list = rp->info) != NULL) { rinfo = listgetdata(listhead(list)); if (ripng_route_rte(rinfo)) @@ -2834,13 +2836,13 @@ void ripng_clean() } list_delete_and_null(&list); rp->info = NULL; - route_unlock_node(rp); + agg_unlock_node(rp); } if ((aggregate = rp->aggregate) != NULL) { ripng_aggregate_free(aggregate); rp->aggregate = NULL; - route_unlock_node(rp); + agg_unlock_node(rp); } } @@ -2862,17 +2864,19 @@ void ripng_clean() } /* Static RIPng route configuration. */ - for (rp = route_top(ripng->route); rp; rp = route_next(rp)) + for (rp = agg_route_top(ripng->route); rp; + rp = agg_route_next(rp)) if (rp->info) { rp->info = NULL; - route_unlock_node(rp); + agg_unlock_node(rp); } /* RIPng aggregated prefixes */ - for (rp = route_top(ripng->aggregate); rp; rp = route_next(rp)) + for (rp = agg_route_top(ripng->aggregate); rp; + rp = agg_route_next(rp)) if (rp->info) { rp->info = NULL; - route_unlock_node(rp); + agg_unlock_node(rp); } for (i = 0; i < ZEBRA_ROUTE_MAX; i++) diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index 534905d895..1095a33494 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -109,13 +109,13 @@ struct ripng { struct stream *obuf; /* RIPng routing information base. */ - struct route_table *table; + struct agg_table *table; /* RIPng only static route information. */ - struct route_table *route; + struct agg_table *route; /* RIPng aggregate route information. */ - struct route_table *aggregate; + struct agg_table *aggregate; /* RIPng threads. */ struct thread *t_read; @@ -198,7 +198,7 @@ struct ripng_info { uint8_t metric_out; uint16_t tag_out; - struct route_node *rp; + struct agg_node *rp; }; #ifdef notyet @@ -377,8 +377,8 @@ extern void ripng_redistribute_withdraw(int type); extern void ripng_distribute_update_interface(struct interface *); extern void ripng_if_rmap_update_interface(struct interface *); -extern void ripng_zebra_ipv6_add(struct route_node *); -extern void ripng_zebra_ipv6_delete(struct route_node *); +extern void ripng_zebra_ipv6_add(struct agg_node *node); +extern void ripng_zebra_ipv6_delete(struct agg_node *node); extern void ripng_redistribute_clean(void); extern int ripng_redistribute_check(int); diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 956da9d4ed..9462eb575c 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -81,13 +81,14 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd, DEFPY (install_routes, install_routes_cmd, - "sharp install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes [instance (0-255)$instance]", + "sharp install routes A.B.C.D$start nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6> (1-1000000)$routes [instance (0-255)$instance]", "Sharp routing Protocol\n" "install some routes\n" "Routes to install\n" "Address to start /32 generation at\n" - "Nexthop to use\n" - "Nexthop address\n" + "Nexthop to use(Can be an IPv4 or IPv6 address)\n" + "V4 Nexthop address to use\n" + "V6 Nexthop address to use\n" "How many to create\n" "Instance to use\n" "Instance\n") @@ -107,8 +108,13 @@ DEFPY (install_routes, p.prefixlen = 32; p.u.prefix4 = start; - nhop.gate.ipv4 = nexthop; - nhop.type = NEXTHOP_TYPE_IPV4; + if (nexthop4.s_addr != INADDR_ANY) { + nhop.gate.ipv4 = nexthop4; + nhop.type = NEXTHOP_TYPE_IPV4; + } else { + memcpy(&nhop.gate.ipv6, &nexthop6, IPV6_MAX_BYTELEN); + nhop.type = NEXTHOP_TYPE_IPV6; + } zlog_debug("Inserting %ld routes", routes); diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index fcb555170b..286f320874 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -193,7 +193,7 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh) api_nh = &api.nexthops[0]; api_nh->vrf_id = VRF_DEFAULT; - api_nh->gate.ipv4 = nh->gate.ipv4; + api_nh->gate = nh->gate; api_nh->type = nh->type; api_nh->ifindex = nh->ifindex; api.nexthop_num = 1; diff --git a/solaris/.gitignore b/solaris/.gitignore index a2c7946e71..a249b61996 100644 --- a/solaris/.gitignore +++ b/solaris/.gitignore @@ -1,5 +1,5 @@ Makefile -Makefile.in +!Makefile.in ?.manifest *.xml pkginfo.*.full @@ -19,4 +19,4 @@ frr.init *.pkg.gz *~ *.loT -*.a
\ No newline at end of file +*.a diff --git a/solaris/Makefile.am b/solaris/Makefile.in index 5633991d1a..df9122a1db 100644 --- a/solaris/Makefile.am +++ b/solaris/Makefile.in @@ -2,13 +2,56 @@ # XXX This file uses GNU make extensions. -.PHONY: packages +.PHONY: packages all all-files + +all: all-files + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datarootdir = @datarootdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +includedir = @includedir@ +infodir = @infodir@ +mandir = @mandir@ +frr_statedir = @frr_statedir@ + +builddir = @builddir@ +srcdir = @srcdir@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ + +enable_user = @enable_user@ +enable_group = @enable_group@ +enable_vty_group = @enable_vty_group@ + +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +CONFDATE = @CONFDATE@ + +host_cpu = @host_cpu@ +host_os = @host_os@ + +SED = @SED@ +MAKE = @MAKE@ # the names of the various subpackages, and some convenient # derived variables. pkg_names = daemons dev doc libs smf pkg_frr_daemons = zebra bgpd ospfd ospf6d ripd ripngd -pkg_name_rev = @PACKAGE_VERSION@-@CONFDATE@-@target_os@-@target_cpu@ +pkg_name_rev = $(PACKAGE_VERSION)-$(CONFDATE)-$(host_os)-$(host_cpu) pkg_depends = $(pkg_names:%=depend.%) pkg_packages = $(pkg_names:%=@PACKAGE_TARNAME@-%-$(pkg_name_rev).pkg) pkg_pkginfos = $(pkg_names:%=pkginfo.%.full) @@ -36,29 +79,28 @@ edit = $(SED) \ -e 's,@enable_group\@,$(enable_group),g' \ -e 's,@enable_vty_group\@,$(enable_vty_group),g' \ -e 's,@frr_statedir\@,$(frr_statedir),g' \ - -e 's,[@]PACKAGE_NAME[@],@PACKAGE_NAME@,g' \ - -e 's,[@]PACKAGE_TARNAME[@],@PACKAGE_TARNAME@,g' \ - -e 's,[@]PACKAGE_VERSION[@],@PACKAGE_VERSION@,g' \ - -e 's,[@]PACKAGE_BUGREPORT[@],@PACKAGE_BUGREPORT@,g' \ - -e 's,[@]CONFDATE[@],@CONFDATE@,g' \ - -e 's,[@]target_cpu[@],$(target_cpu),g' \ - -e 's,[@]target_host[@],$(target_host),g' \ - -e 's,[@]target_os[@],$(target_os),g' + -e 's,[@]PACKAGE_NAME[@],$(PACKAGE_NAME),g' \ + -e 's,[@]PACKAGE_TARNAME[@],$(PACKAGE_TARNAME),g' \ + -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \ + -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \ + -e 's,[@]CONFDATE[@],$(CONFDATE),g' \ + -e 's,[@]host_cpu[@],$(host_cpu),g' \ + -e 's,[@]host_os[@],$(host_os),g' # common options for pkgmk -pkg_make_vars = exec_prefix=@exec_prefix@ prefix=@prefix@ \ - builddir=@builddir@ srcdir=@srcdir@ \ - top_builddir=@top_builddir@ top_srcdir=@top_srcdir@ \ - abs_builddir=@abs_builddir@ abs_srcdir=@abs_srcdir@ \ - abs_top_builddir=@abs_top_builddir@ abs_top_srcdir=@abs_top_srcdir@ +pkg_make_vars = exec_prefix=$(exec_prefix) prefix=$(prefix) \ + builddir=$(builddir) srcdir=$(srcdir) \ + top_builddir=$(top_builddir) top_srcdir=$(top_srcdir) \ + abs_builddir=$(abs_builddir) abs_srcdir=$(abs_srcdir) \ + abs_top_builddir=$(abs_top_builddir) abs_top_srcdir=$(abs_top_srcdir) # pkgmk: write the package to spool in build dir, to avoid root dependencies -pkg_make = pkgmk -o -d @abs_builddir@ \ +pkg_make = pkgmk -o -d $(abs_builddir) \ -f $< DESTDIR="$(DESTDIR)/" $(pkg_make_vars) # pkgtrans: write a pkg file stream, shame we cant pipe directly to it from # pkgmk.. -pkg_trans = pkgtrans -s @abs_builddir@ "@abs_builddir@/$@" +pkg_trans = pkgtrans -s $(abs_builddir) "$(abs_builddir)/$@" # pkgmk can only cope with a single pkginfo, cant 'stack' various # pkginfo template files and a package specific pkginfo file in the prototype @@ -95,7 +137,7 @@ frr.init: $(srcdir)/frr.init.in Makefile $(edit) $< > $@ # construct the pkg -@PACKAGE_TARNAME@-%-$(pkg_name_rev).pkg: prototype.% \ +$(PACKAGE_TARNAME)-%-$(pkg_name_rev).pkg: prototype.% \ depend.% frr.init pkginfo.%.full ($(pkg_make) && \ $(pkg_trans) "FRR$*") @@ -103,22 +145,11 @@ frr.init: $(srcdir)/frr.init.in Makefile %.pkg.gz : %.pkg (gzip -c $< > $@) -# pkginfo.package and prototype.package are all built sources -#BUILT_SOURCES = pkginfo.daemons pkginfo.dev pkginfo.doc pkginfo.libs \ -# prototype.daemons prototype.dev prototype.doc prototype.libs -BUILT_SOURCES = $(pkg_pkginfos) pkginfo.tmpl $(pkg_prototypes) \ - $(pkg_manifests) $(pkg_depends) frr.init - -CLEANFILES = $(BUILT_SOURCES) $(pkg_packages) - -EXTRA_DIST = $(pkg_manifests:%=%.in) $(pkg_prototypes:%=%.in) \ - $(pkg_names:%=pkginfo.%.tmpl.in) $(srcdir)/pkginfo.tmpl.in \ - $(pkg_depends:%=%.in) frr.init.in README.txt - pkg-root-install: (cd $(top_builddir) && \ $(MAKE) DESTDIR=$(abs_builddir)/frr-root install) packages: $(pkg_packages) -#nodist_pkgdata_DATA = $(pkg_packages) +all-files: $(pkg_pkginfos) pkginfo.tmpl $(pkg_prototypes) \ + $(pkg_manifests) $(pkg_depends) frr.init diff --git a/solaris/pkginfo.tmpl.in b/solaris/pkginfo.tmpl.in index 89a281ceb6..ffbf9b9cef 100644 --- a/solaris/pkginfo.tmpl.in +++ b/solaris/pkginfo.tmpl.in @@ -1,4 +1,4 @@ -ARCH="@target_cpu@" +ARCH="@host_cpu@" CATEGORY="system" VERSION="@PACKAGE_VERSION@,REV=@CONFDATE@" VENDOR="http://www.frrouting.org/" diff --git a/solaris/subdir.am b/solaris/subdir.am new file mode 100644 index 0000000000..1d19d56a4d --- /dev/null +++ b/solaris/subdir.am @@ -0,0 +1,53 @@ +# +# solaris +# + +.PHONY: solaris/all +if SOLARIS +all: solaris/all +solaris/all: + @make -s -C solaris all +endif + +CLEANFILES += \ + solaris/frr.xml \ + solaris/frr.init \ + solaris/pkginfo.tmpl \ + solaris/prototype.daemons \ + solaris/prototype.dev \ + solaris/prototype.doc \ + solaris/prototype.libs \ + solaris/prototype.smf \ + solaris/pkginfo.daemons.tmpl \ + solaris/pkginfo.dev.tmpl \ + solaris/pkginfo.doc.tmpl \ + solaris/pkginfo.libs.tmpl \ + solaris/pkginfo.smf.tmpl \ + solaris/depend.daemons \ + solaris/depend.dev \ + solaris/depend.doc \ + solaris/depend.libs \ + solaris/depend.smf \ + # end + +EXTRA_DIST += \ + solaris/frr.xml.in \ + solaris/frr.init.in \ + solaris/pkginfo.tmpl.in \ + solaris/prototype.daemons.in \ + solaris/prototype.dev.in \ + solaris/prototype.doc.in \ + solaris/prototype.libs.in \ + solaris/prototype.smf.in \ + solaris/pkginfo.daemons.tmpl.in \ + solaris/pkginfo.dev.tmpl.in \ + solaris/pkginfo.doc.tmpl.in \ + solaris/pkginfo.libs.tmpl.in \ + solaris/pkginfo.smf.tmpl.in \ + solaris/depend.daemons.in \ + solaris/depend.dev.in \ + solaris/depend.doc.in \ + solaris/depend.libs.in \ + solaris/depend.smf.in \ + solaris/README.txt \ + # end diff --git a/staticd/static_nht.c b/staticd/static_nht.c index c6e4587b6a..44f7fb79da 100644 --- a/staticd/static_nht.c +++ b/staticd/static_nht.c @@ -29,8 +29,8 @@ #include "static_zebra.h" #include "static_nht.h" -void static_nht_update(struct prefix *p, uint32_t nh_num, - afi_t afi, vrf_id_t vrf_id) +void static_nht_update(struct prefix *p, uint32_t nh_num, afi_t afi, + vrf_id_t nh_vrf_id) { struct route_table *stable; struct static_route *si; @@ -40,41 +40,47 @@ void static_nht_update(struct prefix *p, uint32_t nh_num, bool orig; bool reinstall; - vrf = vrf_lookup_by_id(vrf_id); + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + svrf = vrf->info; + if (!svrf) + continue; - if (!vrf || !vrf->info) - return; + stable = static_vrf_static_table(afi, SAFI_UNICAST, svrf); + if (!stable) + continue; - svrf = vrf->info; - stable = static_vrf_static_table(afi, SAFI_UNICAST, svrf); - if (!stable) - return; + for (rn = route_top(stable); rn; rn = route_next(rn)) { + reinstall = false; + for (si = rn->info; si; si = si->next) { + if (si->nh_vrf_id != nh_vrf_id) + continue; - for (rn = route_top(stable); rn; rn = route_next(rn)) { - reinstall = false; - for (si = rn->info; si; si = si->next) { - if (si->type != STATIC_IPV4_GATEWAY && - si->type != STATIC_IPV4_GATEWAY_IFNAME && - si->type != STATIC_IPV6_GATEWAY && - si->type != STATIC_IPV6_GATEWAY_IFNAME) - continue; + if (si->type != STATIC_IPV4_GATEWAY + && si->type != STATIC_IPV4_GATEWAY_IFNAME + && si->type != STATIC_IPV6_GATEWAY + && si->type != STATIC_IPV6_GATEWAY_IFNAME) + continue; - orig = si->nh_valid; - if (p->family == AF_INET && - p->u.prefix4.s_addr == si->addr.ipv4.s_addr) - si->nh_valid = !!nh_num; + orig = si->nh_valid; + if (p->family == AF_INET + && p->u.prefix4.s_addr + == si->addr.ipv4.s_addr) + si->nh_valid = !!nh_num; - if (p->family == AF_INET6 && - memcmp(&p->u.prefix6, &si->addr.ipv6, 16) == 0) - si->nh_valid = !!nh_num; + if (p->family == AF_INET6 + && memcmp(&p->u.prefix6, &si->addr.ipv6, 16) + == 0) + si->nh_valid = !!nh_num; - if (orig != si->nh_valid) - reinstall = true; + if (orig != si->nh_valid) + reinstall = true; - if (reinstall) { - static_zebra_route_add(rn, si, vrf_id, - SAFI_UNICAST, true); - reinstall = false; + if (reinstall) { + static_zebra_route_add( + rn, si, vrf->vrf_id, + SAFI_UNICAST, true); + reinstall = false; + } } } } diff --git a/staticd/static_vrf.c b/staticd/static_vrf.c index d33c1539c8..ad143209ee 100644 --- a/staticd/static_vrf.c +++ b/staticd/static_vrf.c @@ -153,12 +153,18 @@ static int static_vrf_config_write(struct vty *vty) struct vrf *vrf; RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + if (vrf->vrf_id != VRF_DEFAULT) + vty_frame(vty, "vrf %s\n", vrf->name); + static_config(vty, vrf->info, AFI_IP, SAFI_UNICAST, "ip route"); static_config(vty, vrf->info, AFI_IP, SAFI_MULTICAST, "ip mroute"); static_config(vty, vrf->info, AFI_IP6, SAFI_UNICAST, "ipv6 route"); + + if (vrf->vrf_id != VRF_DEFAULT) + vty_endframe(vty, "!\n"); } return 0; diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index a87dc074df..4692dc00d7 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -35,6 +35,7 @@ #include "nexthop.h" #include "nexthop_group.h" #include "hash.h" +#include "jhash.h" #include "static_vrf.h" #include "static_routes.h" @@ -180,6 +181,9 @@ static void zebra_connected(struct zclient *zclient) struct static_nht_data { struct prefix *nh; + + vrf_id_t nh_vrf_id; + uint32_t refcount; uint8_t nh_num; }; @@ -201,13 +205,18 @@ static int static_zebra_nexthop_update(int command, struct zclient *zclient, memset(&lookup, 0, sizeof(lookup)); lookup.nh = &nhr.prefix; + lookup.nh_vrf_id = vrf_id; nhtd = hash_lookup(static_nht_hash, &lookup); - if (nhtd) + + if (nhtd) { nhtd->nh_num = nhr.nexthop_num; + static_nht_update(&nhr.prefix, nhr.nexthop_num, afi, + nhtd->nh_vrf_id); + } else + zlog_err("No nhtd?"); - static_nht_update(&nhr.prefix, nhr.nexthop_num, afi, vrf_id); return 1; } @@ -219,8 +228,10 @@ static void static_zebra_capabilities(struct zclient_capabilities *cap) static unsigned int static_nht_hash_key(void *data) { struct static_nht_data *nhtd = data; + unsigned int key = 0; - return prefix_hash_key(nhtd->nh); + key = prefix_hash_key(nhtd->nh); + return jhash_1word(nhtd->nh_vrf_id, key); } static int static_nht_hash_cmp(const void *d1, const void *d2) @@ -228,6 +239,9 @@ static int static_nht_hash_cmp(const void *d1, const void *d2) const struct static_nht_data *nhtd1 = d1; const struct static_nht_data *nhtd2 = d2; + if (nhtd1->nh_vrf_id != nhtd2->nh_vrf_id) + return 0; + return prefix_same(nhtd1->nh, nhtd2->nh); } @@ -242,6 +256,7 @@ static void *static_nht_hash_alloc(void *data) prefix_copy(new->nh, copy->nh); new->refcount = 0; new->nh_num = 0; + new->nh_vrf_id = copy->nh_vrf_id; return new; } @@ -293,6 +308,7 @@ void static_zebra_nht_register(struct static_route *si, bool reg) memset(&lookup, 0, sizeof(lookup)); lookup.nh = &p; + lookup.nh_vrf_id = si->nh_vrf_id; si->nh_registered = reg; diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index c8e4c025e0..5bff01a506 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -53,7 +53,7 @@ DECLARE_MGROUP(MVTYSH) #define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD #define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD #define VTYSH_NS VTYSH_ZEBRA -#define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD +#define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_STATICD enum vtysh_write_integrated { WRITE_INTEGRATED_UNSPECIFIED, diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index a15d914243..0dcf5082a2 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -259,6 +259,8 @@ static void netlink_determine_zebra_iftype(char *kind, zebra_iftype_t *zif_type) *zif_type = ZEBRA_IF_VXLAN; else if (strcmp(kind, "macvlan") == 0) *zif_type = ZEBRA_IF_MACVLAN; + else if (strcmp(kind, "veth") == 0) + *zif_type = ZEBRA_IF_VETH; } #define parse_rtattr_nested(tb, max, rta) \ @@ -675,7 +677,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup) SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK); /* Update link. */ - zebra_if_update_link(ifp, link_ifindex); + zebra_if_update_link(ifp, link_ifindex, ns_id); /* Hardware type and address. */ ifp->ll_type = netlink_to_zebra_link_type(ifi->ifi_type); @@ -1262,7 +1264,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) ZEBRA_INTERFACE_VRF_LOOPBACK); /* Update link. */ - zebra_if_update_link(ifp, link_ifindex); + zebra_if_update_link(ifp, link_ifindex, ns_id); netlink_interface_update_hw_addr(tb, ifp); diff --git a/zebra/interface.c b/zebra/interface.c index 763931d350..32ee1a566a 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1002,13 +1002,16 @@ void if_refresh(struct interface *ifp) if_get_flags(ifp); } -void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex) +void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex, + ns_id_t ns_id) { struct zebra_if *zif; + if (IS_ZEBRA_IF_VETH(ifp)) + return; zif = (struct zebra_if *)ifp->info; zif->link_ifindex = link_ifindex; - zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), + zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id), link_ifindex); } @@ -1093,6 +1096,10 @@ static const char *zebra_ziftype_2str(zebra_iftype_t zif_type) return "VRF"; break; + case ZEBRA_IF_VETH: + return "VETH"; + break; + default: return "Unknown"; break; diff --git a/zebra/interface.h b/zebra/interface.h index 9634bfdb3f..956d430cf9 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -191,6 +191,7 @@ typedef enum { ZEBRA_IF_BRIDGE, /* bridge device */ ZEBRA_IF_VLAN, /* VLAN sub-interface */ ZEBRA_IF_MACVLAN, /* MAC VLAN interface*/ + ZEBRA_IF_VETH, /* VETH interface*/ } zebra_iftype_t; /* Zebra "slave" interface type */ @@ -312,7 +313,10 @@ static inline void zebra_if_set_ziftype(struct interface *ifp, #define IS_ZEBRA_IF_MACVLAN(ifp) \ (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_MACVLAN) -#define IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) \ +#define IS_ZEBRA_IF_VETH(ifp) \ + (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_VETH) + +#define IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) \ (((struct zebra_if *)(ifp->info))->zif_slave_type \ == ZEBRA_IF_SLAVE_BRIDGE) @@ -344,7 +348,8 @@ extern int if_subnet_add(struct interface *, struct connected *); extern int if_subnet_delete(struct interface *, struct connected *); extern int ipv6_address_configured(struct interface *ifp); extern void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id); -extern void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex); +extern void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex, + ns_id_t ns_id); extern void vrf_add_update(struct vrf *vrfp); diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index f7283aed36..8f48cc5191 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -2698,7 +2698,7 @@ void zebra_mpls_lsp_schedule(struct zebra_vrf *zvrf) * (VTY command handler). */ void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf, - mpls_label_t label, uint8_t use_json) + mpls_label_t label, bool use_json) { struct hash *lsp_table; zebra_lsp_t *lsp; @@ -2729,7 +2729,7 @@ void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf, * Display MPLS label forwarding table (VTY command handler). */ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, - uint8_t use_json) + bool use_json) { char buf[BUFSIZ]; json_object *json = NULL; diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index 65204a67dc..86bee129cf 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -349,13 +349,13 @@ void zebra_mpls_lsp_schedule(struct zebra_vrf *zvrf); * (VTY command handler). */ void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf, - mpls_label_t label, uint8_t use_json); + mpls_label_t label, bool use_json); /* * Display MPLS label forwarding table (VTY command handler). */ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, - uint8_t use_json); + bool use_json); /* * Display MPLS LSP configuration of all static LSPs (VTY command handler). diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c index 2e02b12311..796aa3f666 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -339,7 +339,7 @@ DEFUN (show_mpls_table, JSON_STR) { struct zebra_vrf *zvrf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zvrf = vrf_info_lookup(VRF_DEFAULT); zebra_mpls_print_lsp_table(vty, zvrf, uj); @@ -357,7 +357,7 @@ DEFUN (show_mpls_table_lsp, { uint32_t label; struct zebra_vrf *zvrf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zvrf = vrf_info_lookup(VRF_DEFAULT); label = atoi(argv[3]->arg); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index ab07549ec2..49d2f26943 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2209,7 +2209,6 @@ void _route_entry_dump(const char *func, union prefixconstptr pp, union prefixconstptr src_pp, const struct route_entry *re) { - const struct prefix *p = pp.p; const struct prefix *src_p = src_pp.p; bool is_srcdst = src_p && src_p->prefixlen; char straddr[PREFIX_STRLEN]; @@ -2232,10 +2231,34 @@ void _route_entry_dump(const char *func, union prefixconstptr pp, re->nexthop_num, re->nexthop_active_num); for (ALL_NEXTHOPS(re->ng, nexthop)) { - inet_ntop(p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN); - zlog_debug("%s: %s %s[%u] vrf %u with flags %s%s%s", func, + struct interface *ifp; + struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id); + + switch (nexthop->type) { + case NEXTHOP_TYPE_BLACKHOLE: + sprintf(straddr, "Blackhole"); + break; + case NEXTHOP_TYPE_IFINDEX: + ifp = if_lookup_by_index(nexthop->ifindex, + nexthop->vrf_id); + sprintf(straddr, "%s", ifp ? ifp->name : "Unknown"); + break; + case NEXTHOP_TYPE_IPV4: + /* fallthrough */ + case NEXTHOP_TYPE_IPV4_IFINDEX: + inet_ntop(AF_INET, &nexthop->gate, straddr, + INET6_ADDRSTRLEN); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + inet_ntop(AF_INET6, &nexthop->gate, straddr, + INET6_ADDRSTRLEN); + break; + } + zlog_debug("%s: %s %s[%u] vrf %s(%u) with flags %s%s%s", func, (nexthop->rparent ? " NH" : "NH"), straddr, - nexthop->ifindex, nexthop->vrf_id, + nexthop->ifindex, vrf ? vrf->name : "Unknown", + nexthop->vrf_id, (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""), diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 4f1d5cf6d5..de08e323af 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -55,7 +55,7 @@ extern int allow_delete; static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, - safi_t safi, bool use_fib, uint8_t use_json, + safi_t safi, bool use_fib, bool use_json, route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, @@ -135,7 +135,7 @@ DEFUN (show_ip_rpf, "Display RPF information for multicast source\n" JSON_STR) { - int uj = use_json(argc, argv); + bool uj = use_json(argc, argv); return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST, false, uj, 0, NULL, false, 0, 0); } @@ -760,8 +760,7 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, bool use_fib, route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, - unsigned short ospf_instance_id, - uint8_t use_json) + unsigned short ospf_instance_id, bool use_json) { struct route_node *rn; struct route_entry *re; @@ -850,7 +849,7 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, } static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, - safi_t safi, bool use_fib, uint8_t use_json, + safi_t safi, bool use_fib, bool use_json, route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, @@ -1723,7 +1722,7 @@ DEFUN (show_vrf_vni, struct zebra_vrf *zvrf; json_object *json = NULL; json_object *json_vrfs = NULL; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (uj) { json = json_object_new_object(); @@ -1759,7 +1758,7 @@ DEFUN (show_evpn_global, "EVPN\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zebra_vxlan_print_evpn(vty, uj); return CMD_SUCCESS; @@ -1774,7 +1773,7 @@ DEFUN (show_evpn_vni, JSON_STR) { struct zebra_vrf *zvrf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zvrf = vrf_info_lookup(VRF_DEFAULT); zebra_vxlan_print_vnis(vty, zvrf, uj); @@ -1792,7 +1791,7 @@ DEFUN (show_evpn_vni_vni, { struct zebra_vrf *zvrf; vni_t vni; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[3]->arg, NULL, 10); zvrf = vrf_info_lookup(VRF_DEFAULT); @@ -1814,7 +1813,7 @@ DEFUN (show_evpn_rmac_vni_mac, { vni_t l3vni = 0; struct ethaddr mac; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); l3vni = strtoul(argv[4]->arg, NULL, 10); if (!prefix_str2mac(argv[6]->arg, &mac)) { @@ -1836,7 +1835,7 @@ DEFUN (show_evpn_rmac_vni, JSON_STR) { vni_t l3vni = 0; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); l3vni = strtoul(argv[4]->arg, NULL, 10); zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj); @@ -1854,7 +1853,7 @@ DEFUN (show_evpn_rmac_vni_all, "All VNIs\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zebra_vxlan_print_rmacs_all_l3vni(vty, uj); @@ -1875,7 +1874,7 @@ DEFUN (show_evpn_nh_vni_ip, { vni_t l3vni; struct ipaddr ip; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); l3vni = strtoul(argv[4]->arg, NULL, 10); if (str2ipaddr(argv[6]->arg, &ip) != 0) { @@ -1899,7 +1898,7 @@ DEFUN (show_evpn_nh_vni, JSON_STR) { vni_t l3vni; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); l3vni = strtoul(argv[4]->arg, NULL, 10); zebra_vxlan_print_nh_l3vni(vty, l3vni, uj); @@ -1917,7 +1916,7 @@ DEFUN (show_evpn_nh_vni_all, "All VNIs\n" JSON_STR) { - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zebra_vxlan_print_nh_all_l3vni(vty, uj); @@ -1936,7 +1935,7 @@ DEFUN (show_evpn_mac_vni, { struct zebra_vrf *zvrf; vni_t vni; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); zvrf = vrf_info_lookup(VRF_DEFAULT); @@ -1955,7 +1954,7 @@ DEFUN (show_evpn_mac_vni_all, JSON_STR) { struct zebra_vrf *zvrf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zvrf = vrf_info_lookup(VRF_DEFAULT); zebra_vxlan_print_macs_all_vni(vty, zvrf, uj); @@ -1976,7 +1975,7 @@ DEFUN (show_evpn_mac_vni_all_vtep, { struct zebra_vrf *zvrf; struct in_addr vtep_ip; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); if (!inet_aton(argv[6]->arg, &vtep_ip)) { if (!uj) @@ -2030,7 +2029,7 @@ DEFUN (show_evpn_mac_vni_vtep, struct zebra_vrf *zvrf; vni_t vni; struct in_addr vtep_ip; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); if (!inet_aton(argv[6]->arg, &vtep_ip)) { @@ -2056,7 +2055,7 @@ DEFUN (show_evpn_neigh_vni, { struct zebra_vrf *zvrf; vni_t vni; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); zvrf = vrf_info_lookup(VRF_DEFAULT); @@ -2075,7 +2074,7 @@ DEFUN (show_evpn_neigh_vni_all, JSON_STR) { struct zebra_vrf *zvrf; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); zvrf = vrf_info_lookup(VRF_DEFAULT); zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj); @@ -2097,7 +2096,7 @@ DEFUN (show_evpn_neigh_vni_neigh, struct zebra_vrf *zvrf; vni_t vni; struct ipaddr ip; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); if (str2ipaddr(argv[6]->arg, &ip) != 0) { @@ -2125,7 +2124,7 @@ DEFUN (show_evpn_neigh_vni_vtep, struct zebra_vrf *zvrf; vni_t vni; struct in_addr vtep_ip; - uint8_t uj = use_json(argc, argv); + bool uj = use_json(argc, argv); vni = strtoul(argv[4]->arg, NULL, 10); if (!inet_aton(argv[6]->arg, &vtep_ip)) { diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index b0fc0a39bd..33d0bcd23a 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -79,7 +79,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]); static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, struct ipaddr *ip, uint8_t flags, - uint16_t cmd); + uint32_t seq, uint16_t cmd); static unsigned int neigh_hash_keymake(void *p); static int neigh_cmp(const void *p1, const void *p2); static void *zvni_neigh_alloc(void *p); @@ -93,7 +93,7 @@ static void zvni_neigh_del_all(zebra_vni_t *zvni, int uninstall, int upd_client, static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip); static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, - uint8_t flags); + uint8_t flags, uint32_t seq); static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, uint8_t flags); @@ -147,7 +147,7 @@ static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client, uint32_t flags); static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr); static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, - uint8_t flags); + uint8_t flags, uint32_t seq); static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr, uint8_t flags); static zebra_vni_t *zvni_map_vlan(struct interface *ifp, @@ -296,47 +296,60 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) struct vty *vty; char buf1[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; + const char *type_str; + const char *state_str; + bool flags_present = false; ipaddr2str(&n->ip, buf2, sizeof(buf2)); prefix_mac2str(&n->emac, buf1, sizeof(buf1)); + type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ? + "local" : "remote"; + state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive"; vty = (struct vty *)ctxt; if (json == NULL) { vty_out(vty, "IP: %s\n", ipaddr2str(&n->ip, buf2, sizeof(buf2))); - vty_out(vty, " MAC: %s", + vty_out(vty, " Type: %s\n", type_str); + vty_out(vty, " State: %s\n", state_str); + vty_out(vty, " MAC: %s\n", prefix_mac2str(&n->emac, buf1, sizeof(buf1))); } else { json_object_string_add(json, "ip", buf2); + json_object_string_add(json, "type", type_str); + json_object_string_add(json, "state", state_str); json_object_string_add(json, "mac", buf1); } if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { if (json == NULL) { - vty_out(vty, " Remote VTEP: %s", + vty_out(vty, " Remote VTEP: %s\n", inet_ntoa(n->r_vtep_ip)); } else json_object_string_add(json, "remoteVtep", inet_ntoa(n->r_vtep_ip)); } - if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { - if (!json) { - vty_out(vty, "\n"); - vty_out(vty, " State: %s", - IS_ZEBRA_NEIGH_ACTIVE(n) ? "Active" - : "Inactive"); - } - } if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) { - if (!json) - vty_out(vty, " Default-gateway"); - else + if (!json) { + vty_out(vty, " Flags: Default-gateway"); + flags_present = true; + } else json_object_boolean_true_add(json, "defaultGateway"); } if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) { - if (!json) - vty_out(vty, " Router"); + if (!json) { + vty_out(vty, + flags_present ? " ,Router" : " Flags: Router"); + flags_present = true; + } + } + if (json == NULL) { + if (flags_present) + vty_out(vty, "\n"); + vty_out(vty, " Local Seq: %u Remote Seq: %u\n", + n->loc_seq, n->rem_seq); + } else { + json_object_int_add(json, "localSequence", n->loc_seq); + json_object_int_add(json, "remoteSequence", n->rem_seq); } - if (json == NULL) - vty_out(vty, "\n"); } /* @@ -350,6 +363,7 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt) char buf1[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; struct neigh_walk_ctx *wctx = ctxt; + const char *state_str; vty = wctx->vty; json_vni = wctx->json; @@ -360,55 +374,58 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt) prefix_mac2str(&n->emac, buf1, sizeof(buf1)); ipaddr2str(&n->ip, buf2, sizeof(buf2)); - if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) - && !(wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)) { + state_str = IS_ZEBRA_NEIGH_ACTIVE(n) ? "active" : "inactive"; + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { + if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) + return; + if (json_vni == NULL) { - vty_out(vty, "%*s %-6s %-17s\n", -wctx->addr_width, - buf2, "local", buf1); + vty_out(vty, "%*s %-6s %-8s %-17s\n", + -wctx->addr_width, buf2, "local", + state_str, buf1); } else { json_object_string_add(json_row, "type", "local"); + json_object_string_add(json_row, "state", state_str); json_object_string_add(json_row, "mac", buf1); + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) + json_object_boolean_true_add( + json_row, "defaultGateway"); + json_object_int_add(json_row, "localSequence", + n->loc_seq); + json_object_int_add(json_row, "remoteSequence", + n->rem_seq); } wctx->count++; - } else { - if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) { - if (IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) { - if (json_vni == NULL) { - if (wctx->count == 0) - vty_out(vty, - "%*s %-6s %-17s %-21s\n", - -wctx->addr_width, - "Neighbor", "Type", - "MAC", "Remote VTEP"); - vty_out(vty, "%*s %-6s %-17s %-21s\n", - -wctx->addr_width, buf2, - "remote", buf1, - inet_ntoa(n->r_vtep_ip)); - } else { - json_object_string_add(json_row, "type", - "remote"); - json_object_string_add(json_row, "mac", - buf1); - json_object_string_add( - json_row, "remoteVtep", - inet_ntoa(n->r_vtep_ip)); - } - wctx->count++; - } + } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { + if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) && + !IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) + return; + + if (json_vni == NULL) { + if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) && + (wctx->count == 0)) + vty_out(vty, + "%*s %-6s %-8s %-17s %-21s\n", + -wctx->addr_width, "Neighbor", "Type", + "State", "MAC", "Remote VTEP"); + vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n", + -wctx->addr_width, buf2, "remote", state_str, + buf1, inet_ntoa(n->r_vtep_ip)); } else { - if (json_vni == NULL) { - vty_out(vty, "%*s %-6s %-17s %-21s\n", - -wctx->addr_width, buf2, "remote", buf1, - inet_ntoa(n->r_vtep_ip)); - } else { - json_object_string_add(json_row, "type", - "remote"); - json_object_string_add(json_row, "mac", buf1); - json_object_string_add(json_row, "remoteVtep", - inet_ntoa(n->r_vtep_ip)); - } - wctx->count++; + json_object_string_add(json_row, "type", "remote"); + json_object_string_add(json_row, "state", state_str); + json_object_string_add(json_row, "mac", buf1); + json_object_string_add(json_row, "remoteVtep", + inet_ntoa(n->r_vtep_ip)); + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) + json_object_boolean_true_add(json_row, + "defaultGateway"); + json_object_int_add(json_row, "localSequence", + n->loc_seq); + json_object_int_add(json_row, "remoteSequence", + n->rem_seq); } + wctx->count++; } if (json_vni) @@ -461,8 +478,9 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet, hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx); if (json == NULL) { - vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP", - "Type", "MAC", "Remote VTEP"); + vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n", + -wctx.addr_width, "IP", "Type", + "State", "MAC", "Remote VTEP"); } hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx); @@ -535,6 +553,8 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty, inet_ntoa(zrmac->fwd_info.r_vtep_ip)); json_object_int_add(json, "refCount", rb_host_count(&zrmac->host_rb)); + json_object_int_add(json, "localSequence", zrmac->loc_seq); + json_object_int_add(json, "remoteSequence", zrmac->rem_seq); RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb) json_object_array_add( json_hosts, @@ -588,6 +608,10 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt) vty_out(vty, " Remote-gateway Mac "); vty_out(vty, "\n"); + vty_out(vty, " Local Seq: %u Remote Seq: %u", + mac->loc_seq, mac->rem_seq); + vty_out(vty, "\n"); + /* print all the associated neigh */ vty_out(vty, " Neighbors:\n"); if (!listcount(mac->neigh_list)) @@ -596,11 +620,8 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt) for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) { vty_out(vty, " %s %s\n", ipaddr2str(&n->ip, buf2, sizeof(buf2)), - CHECK_FLAG(n->flags, ZEBRA_MAC_LOCAL) - ? (IS_ZEBRA_NEIGH_ACTIVE(n) - ? "Active" - : "Inactive") - : ""); + (IS_ZEBRA_NEIGH_ACTIVE(n) + ? "Active" : "Inactive")); } } @@ -627,13 +648,15 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt) if (json_mac_hdr) json_mac = json_object_new_object(); - if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) - && !(wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)) { + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { struct zebra_ns *zns; ifindex_t ifindex; struct interface *ifp; vlanid_t vid; + if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) + return; + zns = zebra_ns_lookup(NS_DEFAULT); ifindex = mac->fwd_info.local.ifindex; ifp = if_lookup_by_index_per_ns(zns, ifindex); @@ -653,59 +676,46 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt) else json_object_int_add(json_mac, "vlan", vid); } - if (json_mac_hdr == NULL) + if (json_mac_hdr == NULL) { vty_out(vty, "\n"); - else + } else { + json_object_int_add(json_mac, "localSequence", + mac->loc_seq); + json_object_int_add(json_mac, "remoteSequence", + mac->rem_seq); json_object_object_add(json_mac_hdr, buf1, json_mac); + } + wctx->count++; + } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { - if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) { - if (IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, - &wctx->r_vtep_ip)) { - if (wctx->count == 0) { - if (json_mac_hdr == NULL) { - vty_out(vty, "\nVNI %u\n\n", - wctx->zvni->vni); - vty_out(vty, - "%-17s %-6s %-21s %-5s\n", - "MAC", "Type", - "Intf/Remote VTEP", - "VLAN"); - } - } - if (json_mac_hdr == NULL) - vty_out(vty, "%-17s %-6s %-21s\n", buf1, - "remote", - inet_ntoa(mac->fwd_info - .r_vtep_ip)); - else { - json_object_string_add(json_mac, "type", - "remote"); - json_object_string_add( - json_mac, "remoteVtep", - inet_ntoa(mac->fwd_info - .r_vtep_ip)); - json_object_object_add(json_mac_hdr, - buf1, json_mac); - } - wctx->count++; + + if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) && + !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, + &wctx->r_vtep_ip)) + return; + + if (json_mac_hdr == NULL) { + if ((wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) && + (wctx->count == 0)) { + vty_out(vty, "\nVNI %u\n\n", wctx->zvni->vni); + vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", + "Type", "Intf/Remote VTEP", "VLAN"); } + vty_out(vty, "%-17s %-6s %-21s\n", buf1, "remote", + inet_ntoa(mac->fwd_info.r_vtep_ip)); } else { - if (json_mac_hdr == NULL) - vty_out(vty, "%-17s %-6s %-21s\n", buf1, - "remote", + json_object_string_add(json_mac, "type", "remote"); + json_object_string_add(json_mac, "remoteVtep", inet_ntoa(mac->fwd_info.r_vtep_ip)); - else { - json_object_string_add(json_mac, "type", - "remote"); - json_object_string_add( - json_mac, "remoteVtep", - inet_ntoa(mac->fwd_info.r_vtep_ip)); - json_object_object_add(json_mac_hdr, buf1, - json_mac); - } - wctx->count++; + json_object_object_add(json_mac_hdr, buf1, json_mac); + json_object_int_add(json_mac, "localSequence", + mac->loc_seq); + json_object_int_add(json_mac, "remoteSequence", + mac->rem_seq); } + + wctx->count++; } } @@ -1166,7 +1176,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]) */ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, struct ipaddr *ip, uint8_t flags, - uint16_t cmd) + uint32_t seq, uint16_t cmd) { char buf[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; @@ -1197,7 +1207,10 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, } else stream_putl(s, 0); /* Just MAC. */ - stream_putc(s, flags); /* sticky mac/gateway mac */ + if (cmd == ZEBRA_MACIP_ADD) { + stream_putc(s, flags); /* sticky mac/gateway mac */ + stream_putl(s, seq); /* sequence number */ + } /* Write packet size. */ @@ -1205,10 +1218,10 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s", + "Send MACIP %s flags 0x%x MAC %s IP %s seq %u L2-VNI %u to %s", (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags, prefix_mac2str(macaddr, buf, sizeof(buf)), - ipaddr2str(ip, buf2, sizeof(buf2)), vni, + ipaddr2str(ip, buf2, sizeof(buf2)), seq, vni, zebra_route_string(client->proto)); if (cmd == ZEBRA_MACIP_ADD) @@ -1393,106 +1406,100 @@ static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip) return n; } -/* Process all neigh associated to a mac upon local mac add event */ -static void zvni_process_neigh_on_local_mac_add(zebra_vni_t *zvni, - zebra_mac_t *zmac) +/* + * Process all neighbors associated with a MAC upon the MAC being learnt + * locally or undergoing any other change (such as sequence number). + */ +static void zvni_process_neigh_on_local_mac_change(zebra_vni_t *zvni, + zebra_mac_t *zmac, + bool seq_change) { zebra_neigh_t *n = NULL; struct listnode *node = NULL; char buf[ETHER_ADDR_STRLEN]; - char buf2[INET6_ADDRSTRLEN]; + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Processing neighbors on local MAC %s %s, VNI %u", + prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)), + seq_change ? "CHANGE" : "ADD", zvni->vni); + + /* Walk all neighbors and mark any inactive local neighbors as + * active and/or update sequence number upon a move, and inform BGP. + * The action for remote neighbors is TBD. + * NOTE: We can't simply uninstall remote neighbors as the kernel may + * accidentally end up deleting a just-learnt local neighbor. + */ for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) { if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { - /* MAC is learnt locally, program all inactive neigh - * pointing to this mac */ - if (IS_ZEBRA_NEIGH_INACTIVE(n)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE", - ipaddr2str(&n->ip, buf2, - sizeof(buf2)), - prefix_mac2str(&n->emac, buf, - sizeof(buf)), - zvni->vni); - + if (IS_ZEBRA_NEIGH_INACTIVE(n) || seq_change) { ZEBRA_NEIGH_SET_ACTIVE(n); + n->loc_seq = zmac->loc_seq; zvni_neigh_send_add_to_client( - zvni->vni, &n->ip, &n->emac, n->flags); - } else { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE", - ipaddr2str(&n->ip, buf2, - sizeof(buf2)), - prefix_mac2str(&n->emac, buf, - sizeof(buf)), - zvni->vni); + zvni->vni, &n->ip, &n->emac, + n->flags, n->loc_seq); } - } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { - /* TODO: assume the neigh has moved too ?? */ } } } -/* Process all neigh associated to a mac upon local mac del event */ +/* + * Process all neighbors associated with a local MAC upon the MAC being + * deleted. + */ static void zvni_process_neigh_on_local_mac_del(zebra_vni_t *zvni, zebra_mac_t *zmac) { zebra_neigh_t *n = NULL; struct listnode *node = NULL; char buf[ETHER_ADDR_STRLEN]; - char buf2[INET6_ADDRSTRLEN]; + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Processing neighbors on local MAC %s DEL, VNI %u", + prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)), + zvni->vni); + + /* Walk all local neighbors and mark as inactive and inform + * BGP, if needed. + * TBD: There is currently no handling for remote neighbors. We + * don't expect them to exist, if they do, do we install the MAC + * as a remote MAC and the neighbor as remote? + */ for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) { if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { if (IS_ZEBRA_NEIGH_ACTIVE(n)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE", - ipaddr2str(&n->ip, buf2, - sizeof(buf2)), - prefix_mac2str(&n->emac, buf, - sizeof(buf)), - zvni->vni); - ZEBRA_NEIGH_SET_INACTIVE(n); + n->loc_seq = 0; zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0); } - } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) - && IS_ZEBRA_DEBUG_VXLAN) { - zlog_debug( - "local MAC %s getting deleted on VNI %u has remote neigh %s", - prefix_mac2str(&n->emac, buf, sizeof(buf)), - zvni->vni, - ipaddr2str(&n->ip, buf2, sizeof(buf2))); } } } -/* process all neigh associated to a mac entry upon remote mac add */ +/* + * Process all neighbors associated with a MAC upon the MAC being remotely + * learnt. + */ static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni, zebra_mac_t *zmac) { zebra_neigh_t *n = NULL; struct listnode *node = NULL; char buf[ETHER_ADDR_STRLEN]; - char buf2[INET6_ADDRSTRLEN]; + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Processing neighbors on remote MAC %s ADD, VNI %u", + prefix_mac2str(&zmac->macaddr, buf, sizeof(buf)), + zvni->vni); + + /* Walk all local neighbors and mark as inactive and inform + * BGP, if needed. + */ for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) { if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { if (IS_ZEBRA_NEIGH_ACTIVE(n)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE", - ipaddr2str(&n->ip, buf2, - sizeof(buf2)), - prefix_mac2str(&n->emac, buf, - sizeof(buf)), - zvni->vni); - ZEBRA_NEIGH_SET_INACTIVE(n); + n->loc_seq = 0; zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0); } @@ -1500,25 +1507,14 @@ static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni, } } -/* process all neigh associated to mac entry upon remote mac del */ +/* + * Process all neighbors associated with a remote MAC upon the MAC being + * deleted. + */ static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni, zebra_mac_t *zmac) { - zebra_neigh_t *n = NULL; - struct listnode *node = NULL; - char buf[ETHER_ADDR_STRLEN]; - char buf2[INET6_ADDRSTRLEN]; - - for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) { - if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) - && IS_ZEBRA_DEBUG_VXLAN) { - zlog_debug( - "remote MAC %s getting deleted on VNI %u has local neigh %s", - prefix_mac2str(&n->emac, buf, sizeof(buf)), - zvni->vni, - ipaddr2str(&n->ip, buf2, sizeof(buf2))); - } - } + /* NOTE: Currently a NO-OP. */ } /* @@ -1526,7 +1522,8 @@ static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni, */ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, - uint8_t neigh_flags) + uint8_t neigh_flags, + uint32_t seq) { uint8_t flags = 0; @@ -1537,7 +1534,7 @@ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip, SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags, - ZEBRA_MACIP_ADD); + seq, ZEBRA_MACIP_ADD); } /* @@ -1547,7 +1544,7 @@ static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip, struct ethaddr *macaddr, uint8_t flags) { return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags, - ZEBRA_MACIP_DEL); + 0, ZEBRA_MACIP_DEL); } /* @@ -1578,6 +1575,7 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n) flags = NTF_EXT_LEARNED; if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG) flags |= NTF_ROUTER; + ZEBRA_NEIGH_SET_ACTIVE(n); ret = kernel_add_neigh(vlan_if, &n->ip, &n->emac, flags); #endif return ret; @@ -1609,6 +1607,8 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n) if (!vlan_if) return -1; + ZEBRA_NEIGH_SET_INACTIVE(n); + n->loc_seq = 0; return kernel_del_neigh(vlan_if, &n->ip); } @@ -1802,6 +1802,7 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, /* Set "local" forwarding info. */ SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW); + ZEBRA_NEIGH_SET_ACTIVE(n); /* Set Router flag (R-bit) */ if (ip->ipa_type == IPADDR_V6) SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); @@ -1819,7 +1820,8 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni, prefix_mac2str(macaddr, buf, sizeof(buf)), ipaddr2str(ip, buf2, sizeof(buf2)), n->flags); - zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags); + zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, + n->flags, n->loc_seq); return 0; } @@ -1963,11 +1965,15 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, char buf2[INET6_ADDRSTRLEN]; zebra_neigh_t *n = NULL; zebra_mac_t *zmac = NULL, *old_zmac = NULL; + uint32_t old_mac_seq = 0, mac_new_seq = 0; + bool upd_mac_seq = false; + bool neigh_mac_change = false; bool check_rbit = false; - /* create a dummy MAC if the MAC is not already present */ + /* Check if the MAC exists. */ zmac = zvni_mac_lookup(zvni, macaddr); if (!zmac) { + /* create a dummy MAC if the MAC is not already present */ if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "AUTO MAC %s created for neigh %s on VNI %u", @@ -1985,15 +1991,40 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info)); memset(&zmac->flags, 0, sizeof(uint32_t)); SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO); + } else { + if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) { + /* + * We don't change the MAC to local upon a neighbor + * learn event, we wait for the explicit local MAC + * learn. However, we have to compute its sequence + * number in preparation for when it actually turns + * local. + */ + upd_mac_seq = true; + } } - /* If same entry already exists, it might be a change or it might be a - * move from remote to local. - */ + /* Check if the neighbor exists. */ n = zvni_neigh_lookup(zvni, ip); - if (n) { + if (!n) { + /* New neighbor - create */ + n = zvni_neigh_add(zvni, ip, macaddr); + if (!n) { + flog_err( + ZEBRA_ERR_MAC_ADD_FAILED, + "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u", + ipaddr2str(ip, buf2, sizeof(buf2)), + prefix_mac2str(macaddr, buf, sizeof(buf)), + ifp->name, ifp->ifindex, zvni->vni); + return -1; + } + /* Set "local" forwarding info. */ + SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); + n->ifindex = ifp->ifindex; + check_rbit = true; + } else { if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { - + /* If there is no MAC change, BGP isn't interested. */ if (router_flag != (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG) ? 1 : 0)) @@ -2007,16 +2038,26 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, n->ifindex = ifp->ifindex; } else { - /* If the MAC has changed, - * need to issue a delete first - * as this means a different MACIP route. - * Also, need to do some unlinking/relinking. + /* If the MAC has changed, need to issue a + * delete first as this means a different + * MACIP route. Also, need to do some + * unlinking/relinking. We also need to + * update the MAC's sequence number + * in different situations. */ - zvni_neigh_send_del_to_client(zvni->vni, &n->ip, - &n->emac, 0); + if (IS_ZEBRA_NEIGH_ACTIVE(n)) + zvni_neigh_send_del_to_client( + zvni->vni, &n->ip, &n->emac, 0); old_zmac = zvni_mac_lookup(zvni, &n->emac); if (old_zmac) { - listnode_delete(old_zmac->neigh_list, n); + old_mac_seq = + CHECK_FLAG(old_zmac->flags, + ZEBRA_MAC_REMOTE) ? + old_zmac->rem_seq : + old_zmac->loc_seq; + neigh_mac_change = upd_mac_seq = true; + listnode_delete( + old_zmac->neigh_list, n); zvni_deref_ip2mac(zvni, old_zmac, 0); } @@ -2028,14 +2069,21 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, listnode_add_sort(zmac->neigh_list, n); } - } else - /* Neighbor has moved from remote to local. */ - { - /* If MAC has changed, do the unlink/link */ + } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) { + /* + * Neighbor has moved from remote to local. Its + * MAC could have also changed as part of the move. + */ if (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN) != 0) { old_zmac = zvni_mac_lookup(zvni, &n->emac); if (old_zmac) { + old_mac_seq = CHECK_FLAG( + old_zmac->flags, + ZEBRA_MAC_REMOTE) ? + old_zmac->rem_seq : + old_zmac->loc_seq; + neigh_mac_change = upd_mac_seq = true; listnode_delete(old_zmac->neigh_list, n); zvni_deref_ip2mac(zvni, old_zmac, 0); @@ -2053,22 +2101,19 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, n->ifindex = ifp->ifindex; check_rbit = true; } - } else { - /* New neighbor - create */ - n = zvni_neigh_add(zvni, ip, macaddr); - if (!n) { - flog_err( - ZEBRA_ERR_MAC_ADD_FAILED, - "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u", - ipaddr2str(ip, buf2, sizeof(buf2)), - prefix_mac2str(macaddr, buf, sizeof(buf)), - ifp->name, ifp->ifindex, zvni->vni); - return -1; - } - /* Set "local" forwarding info. */ - SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); - n->ifindex = ifp->ifindex; - check_rbit = true; + } + + /* If MAC was previously remote, or the neighbor had a different + * MAC earlier, recompute the sequence number. + */ + if (upd_mac_seq) { + uint32_t seq1, seq2; + + seq1 = CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE) ? + zmac->rem_seq + 1 : zmac->loc_seq; + seq2 = neigh_mac_change ? old_mac_seq + 1 : 0; + mac_new_seq = zmac->loc_seq < MAX(seq1, seq2) ? + MAX(seq1, seq2) : zmac->loc_seq; } /*Mark Router flag (R-bit) */ @@ -2078,38 +2123,40 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); /* Before we program this in BGP, we need to check if MAC is locally - * learnt as well + * learnt. If not, force neighbor to be inactive and reset its seq. */ if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "Skipping neigh %s add to client as MAC %s is not local on VNI %u with flags 0x%x", - ipaddr2str(ip, buf2, sizeof(buf2)), - prefix_mac2str(macaddr, buf, sizeof(buf)), - zvni->vni, n->flags); - + ZEBRA_NEIGH_SET_INACTIVE(n); + n->loc_seq = 0; + zmac->loc_seq = mac_new_seq; return 0; } - if (!check_rbit) { + if (!check_rbit) + return 0; + + /* If the MAC's sequence number has changed, inform the MAC and all + * neighbors associated with the MAC to BGP, else just inform this + * neighbor. + */ + if (upd_mac_seq && zmac->loc_seq != mac_new_seq) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "Skipping neigh %s with MAC %s on VNI %u add to client as router flag is not set.", - ipaddr2str(ip, buf2, sizeof(buf2)), - prefix_mac2str(macaddr, buf, sizeof(buf)), - zvni->vni); + zlog_debug("Seq changed for MAC %s VNI %u - old %u new %u", + prefix_mac2str(macaddr, buf, sizeof(buf)), + zvni->vni, zmac->loc_seq, mac_new_seq); + zmac->loc_seq = mac_new_seq; + if (zvni_mac_send_add_to_client(zvni->vni, macaddr, + zmac->flags, zmac->loc_seq)) + return -1; + zvni_process_neigh_on_local_mac_change(zvni, zmac, 1); return 0; } - /* Inform BGP. */ - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Neigh %s (MAC %s) is now ACTIVE on L2-VNI %u with flags 0x%x", - ipaddr2str(ip, buf2, sizeof(buf2)), - prefix_mac2str(macaddr, buf, sizeof(buf)), - zvni->vni, n->flags); ZEBRA_NEIGH_SET_ACTIVE(n); + n->loc_seq = zmac->loc_seq; - return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags); + return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, + n->flags, n->loc_seq); } static int zvni_remote_neigh_update(zebra_vni_t *zvni, @@ -2325,7 +2372,7 @@ static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac) * Inform BGP about local MAC addition. */ static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, - uint8_t mac_flags) + uint8_t mac_flags, uint32_t seq) { uint8_t flags = 0; @@ -2335,7 +2382,7 @@ static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr, SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW); return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags, - ZEBRA_MACIP_ADD); + seq, ZEBRA_MACIP_ADD); } /* @@ -2352,7 +2399,7 @@ static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr, SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW); return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags, - ZEBRA_MACIP_DEL); + 0, ZEBRA_MACIP_DEL); } /* @@ -3976,6 +4023,379 @@ static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t *zl3vni, return 0; } +/* Process a remote MACIP add from BGP. */ +static void process_remote_macip_add(vni_t vni, + struct ethaddr *macaddr, + uint16_t ipa_len, + struct ipaddr *ipaddr, + uint8_t flags, + uint32_t seq, + struct in_addr vtep_ip) +{ + zebra_vni_t *zvni; + zebra_vtep_t *zvtep; + zebra_mac_t *mac, *old_mac; + zebra_neigh_t *n = NULL; + int update_mac = 0, update_neigh = 0; + char buf[ETHER_ADDR_STRLEN]; + char buf1[INET6_ADDRSTRLEN]; + struct interface *ifp = NULL; + struct zebra_if *zif = NULL; + uint32_t tmp_seq; + uint8_t sticky = 0; + uint8_t remote_gw = 0; + uint8_t router_flag = 0; + + /* Locate VNI hash entry - expected to exist. */ + zvni = zvni_lookup(vni); + if (!zvni) { + zlog_warn("Unknown VNI %u upon remote MACIP ADD", vni); + return; + } + + ifp = zvni->vxlan_if; + if (ifp) + zif = ifp->info; + if (!ifp || + !if_is_operative(ifp) || + !zif || + !zif->brslave_info.br_if) { + zlog_warn("Ignoring remote MACIP ADD VNI %u, invalid interface state or info", + vni); + return; + } + + /* The remote VTEP specified should normally exist, but it is + * possible that when peering comes up, peer may advertise MACIP + * routes before advertising type-3 routes. + */ + zvtep = zvni_vtep_find(zvni, &vtep_ip); + if (!zvtep) { + if (zvni_vtep_add(zvni, &vtep_ip) == NULL) { + flog_err( + ZEBRA_ERR_VTEP_ADD_FAILED, + "Failed to add remote VTEP, VNI %u zvni %p upon remote MACIP ADD", + vni, zvni); + return; + } + + zvni_vtep_install(zvni, &vtep_ip); + } + + sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY); + remote_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW); + router_flag = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); + + mac = zvni_mac_lookup(zvni, macaddr); + + /* Ignore if the mac is already present as a gateway mac */ + if (mac && + CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) && + CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as MAC is already configured as gateway MAC", + vni, + prefix_mac2str(macaddr, buf, sizeof(buf)), + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(ipaddr, buf1, sizeof(buf1)) : ""); + return; + } + + /* check if the remote MAC is unknown or has a change. + * If so, that needs to be updated first. Note that client could + * install MAC and MACIP separately or just install the latter. + */ + if (!mac + || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) + || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0) != sticky + || (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? 1 : 0) + != remote_gw + || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip) + || seq != mac->rem_seq) + update_mac = 1; + + if (update_mac) { + if (!mac) { + mac = zvni_mac_add(zvni, macaddr); + if (!mac) { + zlog_warn( + "Failed to add MAC %s VNI %u Remote VTEP %s", + prefix_mac2str(macaddr, buf, + sizeof(buf)), + vni, inet_ntoa(vtep_ip)); + return; + } + + /* Is this MAC created for a MACIP? */ + if (ipa_len) + SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); + } else { + const char *mac_type; + + /* When host moves but changes its (MAC,IP) + * binding, BGP may install a MACIP entry that + * corresponds to "older" location of the host + * in transient situations (because {IP1,M1} + * is a different route from {IP1,M2}). Check + * the sequence number and ignore this update + * if appropriate. + */ + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { + tmp_seq = mac->loc_seq; + mac_type = "local"; + } else { + tmp_seq = mac->rem_seq; + mac_type = "remote"; + } + if (seq < tmp_seq) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s MAC has higher seq %u", + vni, + prefix_mac2str(macaddr, + buf, sizeof(buf)), + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(ipaddr, + buf1, sizeof(buf1)) : "", + mac_type, + tmp_seq); + return; + } + } + + /* Set "auto" and "remote" forwarding info. */ + UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); + memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); + SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); + mac->fwd_info.r_vtep_ip = vtep_ip; + + if (sticky) + SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); + else + UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); + + if (remote_gw) + SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW); + else + UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW); + + zvni_process_neigh_on_remote_mac_add(zvni, mac); + + /* Install the entry. */ + zvni_mac_install(zvni, mac); + } + + /* Update seq number. */ + mac->rem_seq = seq; + + /* If there is no IP, return after clearing AUTO flag of MAC. */ + if (!ipa_len) { + UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO); + return; + } + + /* Check if the remote neighbor itself is unknown or has a + * change. If so, create or update and then install the entry. + */ + n = zvni_neigh_lookup(zvni, ipaddr); + if (!n + || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) + || (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0) + || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip) + || ((CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG) ? 1 : 0) + != router_flag) + || seq != n->rem_seq) + update_neigh = 1; + + if (update_neigh) { + if (!n) { + n = zvni_neigh_add(zvni, ipaddr, macaddr); + if (!n) { + zlog_warn( + "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s", + ipaddr2str(ipaddr, buf1, + sizeof(buf1)), + prefix_mac2str(macaddr, buf, + sizeof(buf)), + vni, inet_ntoa(vtep_ip)); + return; + } + + } else { + const char *n_type; + + /* When host moves but changes its (MAC,IP) + * binding, BGP may install a MACIP entry that + * corresponds to "older" location of the host + * in transient situations (because {IP1,M1} + * is a different route from {IP1,M2}). Check + * the sequence number and ignore this update + * if appropriate. + */ + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { + tmp_seq = n->loc_seq; + n_type = "local"; + } else { + tmp_seq = n->rem_seq; + n_type = "remote"; + } + if (seq < tmp_seq) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u", + vni, + prefix_mac2str(macaddr, + buf, sizeof(buf)), + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(ipaddr, + buf1, sizeof(buf1)) : "", + n_type, + tmp_seq); + return; + } + if (memcmp(&n->emac, macaddr, sizeof(*macaddr)) != 0) { + /* MAC change, send a delete for old + * neigh if learnt locally. + */ + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) && + IS_ZEBRA_NEIGH_ACTIVE(n)) + zvni_neigh_send_del_to_client( + zvni->vni, &n->ip, + &n->emac, 0); + + /* update neigh list for macs */ + old_mac = zvni_mac_lookup(zvni, &n->emac); + if (old_mac) { + listnode_delete(old_mac->neigh_list, n); + zvni_deref_ip2mac(zvni, old_mac, 1); + } + listnode_add_sort(mac->neigh_list, n); + memcpy(&n->emac, macaddr, ETH_ALEN); + } + } + + /* Set "remote" forwarding info. */ + UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); + n->r_vtep_ip = vtep_ip; + SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE); + + /* Set router flag (R-bit) to this Neighbor entry */ + if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG)) + SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); + else + UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); + + /* Install the entry. */ + zvni_neigh_install(zvni, n); + } + + /* Update seq number. */ + n->rem_seq = seq; +} + +/* Process a remote MACIP delete from BGP. */ +static void process_remote_macip_del(vni_t vni, + struct ethaddr *macaddr, + uint16_t ipa_len, + struct ipaddr *ipaddr, + struct in_addr vtep_ip) +{ + zebra_vni_t *zvni; + zebra_mac_t *mac = NULL; + zebra_neigh_t *n = NULL; + struct interface *ifp = NULL; + struct zebra_if *zif = NULL; + char buf[ETHER_ADDR_STRLEN]; + char buf1[INET6_ADDRSTRLEN]; + + /* Locate VNI hash entry - expected to exist. */ + zvni = zvni_lookup(vni); + if (!zvni) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni); + return; + } + + ifp = zvni->vxlan_if; + if (ifp) + zif = ifp->info; + if (!ifp || + !if_is_operative(ifp) || + !zif || + !zif->brslave_info.br_if) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Ignoring remote MACIP DEL VNI %u, invalid interface state or info", + vni); + return; + } + + /* The remote VTEP specified is normally expected to exist, but + * it is possible that the peer may delete the VTEP before deleting + * any MACs referring to the VTEP, in which case the handler (see + * remote_vtep_del) would have already deleted the MACs. + */ + if (!zvni_vtep_find(zvni, &vtep_ip)) + return; + + mac = zvni_mac_lookup(zvni, macaddr); + if (ipa_len) + n = zvni_neigh_lookup(zvni, ipaddr); + + if (n && !mac) { + zlog_warn("Failed to locate MAC %s for neigh %s VNI %u upon remote MACIP DEL", + prefix_mac2str(macaddr, buf, sizeof(buf)), + ipaddr2str(ipaddr, buf1, sizeof(buf1)), vni); + return; + } + + /* If the remote mac or neighbor doesn't exist there is nothing + * more to do. Otherwise, uninstall the entry and then remove it. + */ + if (!mac && !n) + return; + + /* Ignore the delete if this mac is a gateway mac-ip */ + if (mac + && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) + && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) { + zlog_warn( + "Ignore remote MACIP DEL VNI %u MAC %s%s%s as MAC is already configured as gateway MAC", + vni, + prefix_mac2str(macaddr, buf, sizeof(buf)), + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(ipaddr, buf1, sizeof(buf1)) : ""); + return; + } + + /* Uninstall remote neighbor or MAC. */ + if (n) { + /* When the MAC changes for an IP, it is possible the + * client may update the new MAC before trying to delete the + * "old" neighbor (as these are two different MACIP routes). + * Do the delete only if the MAC matches. + */ + if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) + && (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN) == 0)) { + zvni_neigh_uninstall(zvni, n); + zvni_neigh_del(zvni, n); + zvni_deref_ip2mac(zvni, mac, 1); + } + } else { + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { + zvni_process_neigh_on_remote_mac_del(zvni, mac); + + if (list_isempty(mac->neigh_list)) { + zvni_mac_uninstall(zvni, mac, 0); + zvni_mac_del(zvni, mac); + } else + SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); + } + } +} + + /* Public functions */ int is_l3vni_for_prefix_routes_only(vni_t vni) @@ -4057,8 +4477,7 @@ void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id, } void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni, - struct ethaddr *rmac, - uint8_t use_json) + struct ethaddr *rmac, bool use_json) { zebra_l3vni_t *zl3vni = NULL; zebra_mac_t *zrmac = NULL; @@ -4102,8 +4521,7 @@ void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni, } } -void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, - uint8_t use_json) +void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, bool use_json) { zebra_l3vni_t *zl3vni; uint32_t num_rmacs; @@ -4147,7 +4565,7 @@ void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, } } -void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, uint8_t use_json) +void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json) { struct zebra_ns *zns = NULL; json_object *json = NULL; @@ -4184,7 +4602,7 @@ void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, uint8_t use_json) } void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni, - struct ipaddr *ip, uint8_t use_json) + struct ipaddr *ip, bool use_json) { zebra_l3vni_t *zl3vni = NULL; zebra_neigh_t *n = NULL; @@ -4228,7 +4646,7 @@ void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni, } } -void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, uint8_t use_json) +void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, bool use_json) { uint32_t num_nh; struct nh_walk_ctx wctx; @@ -4272,7 +4690,7 @@ void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, uint8_t use_json) } } -void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, uint8_t use_json) +void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json) { struct zebra_ns *zns = NULL; json_object *json = NULL; @@ -4303,13 +4721,12 @@ void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, uint8_t use_json) json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } - return; } /* * Display L3 VNI information (VTY command handler). */ -void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, uint8_t use_json) +void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json) { void *args[2]; json_object *json = NULL; @@ -4362,6 +4779,7 @@ void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf, zl3vni_rmac2str(zl3vni, buf, sizeof(buf))); } else { json_object *json_vrf = NULL; + json_vrf = json_object_new_object(); json_object_string_add(json_vrf, "vrf", zvrf_name(zvrf)); json_object_int_add(json_vrf, "vni", zl3vni->vni); @@ -4382,7 +4800,7 @@ void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf, * Display Neighbors for a VNI (VTY command handler). */ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, uint8_t use_json) + vni_t vni, bool use_json) { zebra_vni_t *zvni; uint32_t num_neigh; @@ -4421,8 +4839,9 @@ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf, vty_out(vty, "Number of ARPs (local and remote) known for this VNI: %u\n", num_neigh); - vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP", - "Type", "MAC", "Remote VTEP"); + vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n", + -wctx.addr_width, "IP", "Type", + "State", "MAC", "Remote VTEP"); } else json_object_int_add(json, "numArpNd", num_neigh); @@ -4438,7 +4857,7 @@ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf, * Display neighbors across all VNIs (VTY command handler). */ void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf, - uint8_t use_json) + bool use_json) { json_object *json = NULL; void *args[2]; @@ -4467,7 +4886,7 @@ void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf, */ void zebra_vxlan_print_specific_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, - struct ipaddr *ip, uint8_t use_json) + struct ipaddr *ip, bool use_json) { zebra_vni_t *zvni; zebra_neigh_t *n; @@ -4509,7 +4928,7 @@ void zebra_vxlan_print_specific_neigh_vni(struct vty *vty, */ void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, struct in_addr vtep_ip, - uint8_t use_json) + bool use_json) { zebra_vni_t *zvni; uint32_t num_neigh; @@ -4551,7 +4970,7 @@ void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, * Display MACs for a VNI (VTY command handler). */ void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, uint8_t use_json) + vni_t vni, bool use_json) { zebra_vni_t *zvni; uint32_t num_macs; @@ -4606,7 +5025,7 @@ void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf, * Display MACs for all VNIs (VTY command handler). */ void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf, - uint8_t use_json) + bool use_json) { struct mac_walk_ctx wctx; json_object *json = NULL; @@ -4636,8 +5055,7 @@ void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf, */ void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, - struct in_addr vtep_ip, - uint8_t use_json) + struct in_addr vtep_ip, bool use_json) { struct mac_walk_ctx wctx; json_object *json = NULL; @@ -4693,7 +5111,7 @@ void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf, */ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, struct in_addr vtep_ip, - uint8_t use_json) + bool use_json) { zebra_vni_t *zvni; uint32_t num_macs; @@ -4743,7 +5161,7 @@ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, * Display VNI information (VTY command handler). */ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, - uint8_t use_json) + bool use_json) { json_object *json = NULL; void *args[2]; @@ -4782,7 +5200,7 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, } /* Display all global details for EVPN */ -void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj) +void zebra_vxlan_print_evpn(struct vty *vty, bool uj) { int num_l2vnis = 0; int num_l3vnis = 0; @@ -4831,7 +5249,7 @@ void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj) * Display VNI hash table (VTY command handler). */ void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf, - uint8_t use_json) + bool use_json) { json_object *json = NULL; struct zebra_ns *zns = NULL; @@ -5016,14 +5434,9 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) struct ethaddr macaddr; struct ipaddr ip; struct in_addr vtep_ip; - zebra_vni_t *zvni; - zebra_mac_t *mac; - zebra_neigh_t *n; - unsigned short l = 0, ipa_len; + uint16_t l = 0, ipa_len; char buf[ETHER_ADDR_STRLEN]; char buf1[INET6_ADDRSTRLEN]; - struct interface *ifp = NULL; - struct zebra_if *zif = NULL; memset(&macaddr, 0, sizeof(struct ethaddr)); memset(&ip, 0, sizeof(struct ipaddr)); @@ -5036,8 +5449,6 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) /* Message contains VNI, followed by MAC followed by IP (if any) * followed by remote VTEP IP. */ - mac = NULL; - n = NULL; memset(&ip, 0, sizeof(ip)); STREAM_GETL(s, vni); STREAM_GET(&macaddr.octet, s, ETH_ALEN); @@ -5053,103 +5464,17 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s", + "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s", + vni, prefix_mac2str(&macaddr, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni, + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(&ip, buf1, sizeof(buf1)) : "", inet_ntoa(vtep_ip), zebra_route_string(client->proto)); - /* Locate VNI hash entry - expected to exist. */ - zvni = zvni_lookup(vni); - if (!zvni) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "Failed to locate VNI hash upon remote MACIP DEL, " - "VNI %u", - vni); - continue; - } - ifp = zvni->vxlan_if; - if (!ifp) { - zlog_warn( - "VNI %u hash %p doesn't have intf upon remote MACIP DEL", - vni, zvni); - continue; - } - zif = ifp->info; - - /* If down or not mapped to a bridge, we're done. */ - if (!if_is_operative(ifp) || !zif->brslave_info.br_if) - continue; + process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip); - /* The remote VTEP specified is normally expected to exist, but - * it is - * possible that the peer may delete the VTEP before deleting - * any MACs - * referring to the VTEP, in which case the handler (see - * remote_vtep_del) - * would have already deleted the MACs. - */ - if (!zvni_vtep_find(zvni, &vtep_ip)) - continue; - - mac = zvni_mac_lookup(zvni, &macaddr); - if (ipa_len) - n = zvni_neigh_lookup(zvni, &ip); - - if (n && !mac) { - zlog_warn("Failed to locate MAC %s for neigh %s VNI %u", - prefix_mac2str(&macaddr, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni); - continue; - } - - /* If the remote mac or neighbor doesn't exist there is nothing - * more - * to do. Otherwise, uninstall the entry and then remove it. - */ - if (!mac && !n) - continue; - - /* Ignore the delete if this mac is a gateway mac-ip */ - if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) - && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) { - zlog_warn( - "%u: Ignore Del for MAC %s neigh %s on VNI %u as it is configured as a default gateway", - zvrf_id(zvrf), - prefix_mac2str(&macaddr, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni); - continue; - } - - /* Uninstall remote neighbor or MAC. */ - if (n) { - /* When the MAC changes for an IP, it is possible the - * client may - * update the new MAC before trying to delete the "old" - * neighbor - * (as these are two different MACIP routes). Do the - * delete only - * if the MAC matches. - */ - if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) - && (memcmp(n->emac.octet, macaddr.octet, ETH_ALEN) - == 0)) { - zvni_neigh_uninstall(zvni, n); - zvni_neigh_del(zvni, n); - zvni_deref_ip2mac(zvni, mac, 1); - } - } else { - if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { - zvni_process_neigh_on_remote_mac_del(zvni, mac); - - if (list_isempty(mac->neigh_list)) { - zvni_mac_uninstall(zvni, mac, 0); - zvni_mac_del(zvni, mac); - } else - SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); - } - } } stream_failure: @@ -5168,29 +5493,18 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) struct ethaddr macaddr; struct ipaddr ip; struct in_addr vtep_ip; - zebra_vni_t *zvni; - zebra_vtep_t *zvtep; - zebra_mac_t *mac, *old_mac; - zebra_neigh_t *n; - unsigned short l = 0, ipa_len; - int update_mac = 0, update_neigh = 0; + uint16_t l = 0, ipa_len; + uint8_t flags = 0; + uint32_t seq; char buf[ETHER_ADDR_STRLEN]; char buf1[INET6_ADDRSTRLEN]; - uint8_t sticky = 0; - uint8_t remote_gw = 0; - uint8_t router_flag = 0; - uint8_t flags = 0; - struct interface *ifp = NULL; - struct zebra_if *zif = NULL; memset(&macaddr, 0, sizeof(struct ethaddr)); memset(&ip, 0, sizeof(struct ipaddr)); memset(&vtep_ip, 0, sizeof(struct in_addr)); if (!EVPN_ENABLED(zvrf)) { - zlog_warn( - "%s: EVPN Not turned on yet we have received a remote_macip add zapi callback", - __PRETTY_FUNCTION__); + zlog_warn("EVPN not enabled, ignoring remote MACIP ADD"); return; } @@ -5201,9 +5515,6 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) /* Message contains VNI, followed by MAC followed by IP (if any) * followed by remote VTEP IP. */ - update_mac = update_neigh = 0; - mac = NULL; - n = NULL; memset(&ip, 0, sizeof(ip)); STREAM_GETL(s, vni); STREAM_GET(&macaddr.octet, s, ETH_ALEN); @@ -5219,188 +5530,23 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) /* Get flags - sticky mac and/or gateway mac */ STREAM_GETC(s, flags); - sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY); - remote_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW); - router_flag = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); l++; + STREAM_GETL(s, seq); + l += 4; if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Recv MACIP Add MAC %s IP %s VNI %u Remote VTEP %s with flags 0x%x from %s", + "Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s", + vni, prefix_mac2str(&macaddr, buf, sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), vni, - inet_ntoa(vtep_ip), flags, + ipa_len ? " IP " : "", + ipa_len ? + ipaddr2str(&ip, buf1, sizeof(buf1)) : "", + flags, seq, inet_ntoa(vtep_ip), zebra_route_string(client->proto)); - /* Locate VNI hash entry - expected to exist. */ - zvni = zvni_lookup(vni); - if (!zvni) { - zlog_warn( - "Failed to locate VNI hash upon remote MACIP ADD, VNI %u", - vni); - continue; - } - ifp = zvni->vxlan_if; - if (!ifp) { - zlog_warn( - "VNI %u hash %p doesn't have intf upon remote MACIP add", - vni, zvni); - continue; - } - zif = ifp->info; - - /* If down or not mapped to a bridge, we're done. */ - if (!if_is_operative(ifp) || !zif->brslave_info.br_if) - continue; - - /* The remote VTEP specified should normally exist, but it is - * possible - * that when peering comes up, peer may advertise MACIP routes - * before - * advertising type-3 routes. - */ - zvtep = zvni_vtep_find(zvni, &vtep_ip); - if (!zvtep) { - if (zvni_vtep_add(zvni, &vtep_ip) == NULL) { - flog_err( - ZEBRA_ERR_VTEP_ADD_FAILED, - "Failed to add remote VTEP, VNI %u zvni %p", - vni, zvni); - continue; - } - - zvni_vtep_install(zvni, &vtep_ip); - } - - mac = zvni_mac_lookup(zvni, &macaddr); - - /* Ignore the update if the mac is already present - as a gateway mac */ - if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) - && CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "%u:Ignore MAC %s IP %s on VNI %u as MAC is already configured as gateway mac", - zvrf_id(zvrf), - prefix_mac2str(&macaddr, buf, - sizeof(buf)), - ipaddr2str(&ip, buf1, sizeof(buf1)), - vni); - continue; - } - - /* check if the remote MAC is unknown or has a change. - * If so, that needs to be updated first. Note that client could - * install MAC and MACIP separately or just install the latter. - */ - if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) - || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0) - != sticky - || (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? 1 : 0) - != remote_gw - || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip)) - update_mac = 1; - - if (update_mac) { - if (!mac) { - mac = zvni_mac_add(zvni, &macaddr); - if (!mac) { - zlog_warn( - "Failed to add MAC %s VNI %u Remote VTEP %s", - prefix_mac2str(&macaddr, buf, - sizeof(buf)), - vni, inet_ntoa(vtep_ip)); - return; - } - - /* Is this MAC created for a MACIP? */ - if (ipa_len) - SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); - } - - /* Set "auto" and "remote" forwarding info. */ - UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); - memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); - SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); - mac->fwd_info.r_vtep_ip = vtep_ip; - - if (sticky) - SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); - else - UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); - - if (remote_gw) - SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW); - else - UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW); - - zvni_process_neigh_on_remote_mac_add(zvni, mac); - - /* Install the entry. */ - zvni_mac_install(zvni, mac); - } - - /* If there is no IP, continue - after clearing AUTO flag of - * MAC. */ - if (!ipa_len) { - UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO); - continue; - } - - /* Check if the remote neighbor itself is unknown or has a - * change. - * If so, create or update and then install the entry. - */ - n = zvni_neigh_lookup(zvni, &ip); - if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE) - || ((CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG) ? 1 : 0) - != router_flag) - || (memcmp(&n->emac, &macaddr, sizeof(macaddr)) != 0) - || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip)) - update_neigh = 1; - - if (update_neigh) { - if (!n) { - n = zvni_neigh_add(zvni, &ip, &macaddr); - if (!n) { - zlog_warn( - "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s", - ipaddr2str(&ip, buf1, - sizeof(buf1)), - prefix_mac2str(&macaddr, buf, - sizeof(buf)), - vni, inet_ntoa(vtep_ip)); - return; - } - - } else if (memcmp(&n->emac, &macaddr, sizeof(macaddr)) - != 0) { - /* MAC change, update neigh list for old and new - * mac */ - old_mac = zvni_mac_lookup(zvni, &n->emac); - if (old_mac) { - listnode_delete(old_mac->neigh_list, n); - zvni_deref_ip2mac(zvni, old_mac, 1); - } - listnode_add_sort(mac->neigh_list, n); - memcpy(&n->emac, &macaddr, ETH_ALEN); - } - - /* Set "remote" forwarding info. */ - UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); - /* TODO: Handle MAC change. */ - n->r_vtep_ip = vtep_ip; - SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE); - - /* Set router flag (R-bit) to this Neighbor entry */ - if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG)) - SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); - else - UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); - - /* Install the entry. */ - zvni_neigh_install(zvni, n); - } + process_remote_macip_add(vni, &macaddr, ipa_len, &ip, + flags, seq, vtep_ip); } stream_failure: @@ -5546,7 +5692,7 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, } if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u", + zlog_debug("DEL MAC %s intf %s(%u) VID %u -> VNI %u", prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, vid, zvni->vni); @@ -5559,12 +5705,12 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) return 0; - /* Remove MAC from BGP. */ - zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags); - /* Update all the neigh entries associated with this mac */ zvni_process_neigh_on_local_mac_del(zvni, mac); + /* Remove MAC from BGP. */ + zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags); + /* * If there are no neigh associated with the mac delete the mac * else mark it as AUTO for forward reference @@ -5590,8 +5736,9 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, zebra_vni_t *zvni; zebra_mac_t *mac; char buf[ETHER_ADDR_STRLEN]; - int add = 1; - uint8_t mac_sticky; + bool mac_sticky = false; + bool inform_client = false; + bool upd_neigh = false; /* We are interested in MACs only on ports or (port, VLAN) that * map to a VNI. @@ -5613,26 +5760,48 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, return -1; } - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u", - sticky ? "sticky " : "", - prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, - ifp->ifindex, vid, zvni->vni); - - /* If same entry already exists, nothing to do. */ + /* Check if we need to create or update or it is a NO-OP. */ mac = zvni_mac_lookup(zvni, macaddr); - if (mac) { - if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { - mac_sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) - ? 1 - : 0; + if (!mac) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "ADD %sMAC %s intf %s(%u) VID %u -> VNI %u", + sticky ? "sticky " : "", + prefix_mac2str(macaddr, buf, sizeof(buf)), + ifp->name, ifp->ifindex, vid, zvni->vni); + mac = zvni_mac_add(zvni, macaddr); + if (!mac) { + flog_err( + ZEBRA_ERR_MAC_ADD_FAILED, + "Failed to add MAC %s intf %s(%u) VID %u VNI %u", + prefix_mac2str(macaddr, buf, sizeof(buf)), + ifp->name, ifp->ifindex, vid, zvni->vni); + return -1; + } + SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); + mac->fwd_info.local.ifindex = ifp->ifindex; + mac->fwd_info.local.vid = vid; + if (sticky) + SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); + inform_client = true; + + } else { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u curFlags 0x%x", + sticky ? "sticky " : "", + prefix_mac2str(macaddr, buf, sizeof(buf)), + ifp->name, ifp->ifindex, vid, zvni->vni, + mac->flags); + + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) + mac_sticky = true; /* - * return if nothing has changed. - * inform bgp if sticky flag has changed - * update locally and do not inform bgp if local - * parameters like interface has changed + * Update any changes and if changes are relevant to + * BGP, note it. */ if (mac_sticky == sticky && mac->fwd_info.local.ifindex == ifp->ifindex @@ -5647,61 +5816,74 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp, ifp->name, ifp->ifindex, vid, zvni->vni); return 0; - } else if (mac_sticky != sticky) { - add = 1; - } else { - add = 0; /* This is an update of local - interface. */ } - } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { + if (mac_sticky != sticky) { + if (sticky) + SET_FLAG(mac->flags, + ZEBRA_MAC_STICKY); + else + UNSET_FLAG(mac->flags, + ZEBRA_MAC_STICKY); + inform_client = true; + } + + memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); + mac->fwd_info.local.ifindex = ifp->ifindex; + mac->fwd_info.local.vid = vid; + + } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) || + CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) { + /* - * If we have already learned the MAC as a remote sticky - * MAC, - * this is a operator error and we must log a warning + * MAC has either moved or was "internally" created due + * to a neighbor learn and is now actually learnt. If + * it was learnt as a remote sticky MAC, this is an + * operator error. */ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) { zlog_warn( - "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d", + "MAC %s already learnt as remote sticky behind VTEP %s VNI %u", prefix_mac2str(macaddr, buf, sizeof(buf)), inet_ntoa(mac->fwd_info.r_vtep_ip), zvni->vni); return 0; } - } - } - if (!mac) { - mac = zvni_mac_add(zvni, macaddr); - if (!mac) { - flog_err(ZEBRA_ERR_MAC_ADD_FAILED, - "Failed to add MAC %s intf %s(%u) VID %u", - prefix_mac2str(macaddr, buf, sizeof(buf)), - ifp->name, ifp->ifindex, vid); - return -1; + /* If an actual move, compute MAC's seq number */ + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) + mac->loc_seq = MAX(mac->rem_seq + 1, + mac->loc_seq); + UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); + UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO); + SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); + memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); + mac->fwd_info.local.ifindex = ifp->ifindex; + mac->fwd_info.local.vid = vid; + if (sticky) + SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); + else + UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); + /* + * We have to inform BGP of this MAC as well as process + * all neighbors. + */ + inform_client = true; + upd_neigh = true; } } - /* Set "local" forwarding info. */ - UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); - UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO); - SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); - memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); - mac->fwd_info.local.ifindex = ifp->ifindex; - mac->fwd_info.local.vid = vid; - - if (sticky) - SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); - else - UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); - /* Inform BGP if required. */ - if (add) { - zvni_process_neigh_on_local_mac_add(zvni, mac); - return zvni_mac_send_add_to_client(zvni->vni, macaddr, - mac->flags); + if (inform_client) { + if (zvni_mac_send_add_to_client(zvni->vni, macaddr, + mac->flags, mac->loc_seq)) + return -1; } + /* Process all neighbors associated with this MAC, if required. */ + if (upd_neigh) + zvni_process_neigh_on_local_mac_change(zvni, mac, 0); + return 0; } diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 2732ef72ed..5097757b1d 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -68,53 +68,51 @@ extern int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf); extern int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf); extern int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf); extern void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty, vni_t l3vni, - struct ipaddr *ip, uint8_t uj); -extern void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj); + struct ipaddr *ip, bool uj); +extern void zebra_vxlan_print_evpn(struct vty *vty, bool uj); extern void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni, struct ethaddr *rmac, - uint8_t use_json); + bool use_json); extern void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, uint8_t use_json); + vni_t vni, bool use_json); extern void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf, - uint8_t use_json); + bool use_json); extern void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, struct in_addr vtep_ip, - uint8_t use_json); + bool use_json); extern void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, struct ethaddr *mac); extern void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, struct in_addr vtep_ip, - uint8_t use_json); + bool use_json); extern void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, uint8_t use_json); + vni_t vni, bool use_json); extern void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf, - uint8_t use_json); + bool use_json); extern void zebra_vxlan_print_specific_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, struct ipaddr *ip, - uint8_t use_json); + bool use_json); extern void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, struct in_addr vtep_ip, - uint8_t use_json); + bool use_json); extern void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, uint8_t use_json); + vni_t vni, bool use_json); extern void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf, - uint8_t use_json); + bool use_json); extern void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t vni, - uint8_t use_json); -extern void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, - uint8_t use_json); + bool use_json); +extern void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json); extern void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t vni, - uint8_t use_json); -extern void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, uint8_t use_json); -extern void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, - uint8_t use_json); + bool use_json); +extern void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json); +extern void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json); extern void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf, json_object *json_vrfs); extern int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p, diff --git a/zebra/zebra_vxlan_null.c b/zebra/zebra_vxlan_null.c index afc59774c9..00c849a3d0 100644 --- a/zebra/zebra_vxlan_null.c +++ b/zebra/zebra_vxlan_null.c @@ -83,7 +83,7 @@ void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf) { } -void zebra_vxlan_print_evpn(struct vty *vty, uint8_t uj) +void zebra_vxlan_print_evpn(struct vty *vty, bool uj) { } diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h index e86967041b..44163eb331 100644 --- a/zebra/zebra_vxlan_private.h +++ b/zebra/zebra_vxlan_private.h @@ -260,6 +260,10 @@ struct zebra_mac_t_ { struct in_addr r_vtep_ip; } fwd_info; + /* Mobility sequence numbers associated with this entry. */ + uint32_t rem_seq; + uint32_t loc_seq; + /* List of neigh associated with this mac */ struct list *neigh_list; @@ -338,6 +342,16 @@ struct zebra_neigh_t_ { /* Remote VTEP IP - applicable only for remote neighbors. */ struct in_addr r_vtep_ip; + /* + * Mobility sequence numbers associated with this entry. The rem_seq + * represents the sequence number from the client (BGP) for the most + * recent add or update of this entry while the loc_seq represents + * the sequence number informed (or to be informed) by zebra to BGP + * for this entry. + */ + uint32_t rem_seq; + uint32_t loc_seq; + /* list of hosts pointing to this remote NH entry */ struct host_rb_tree_entry host_rb; }; |
