]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #4040 from donaldsharp/pim_cleanup
authorJafar Al-Gharaibeh <Jafaral@users.noreply.github.com>
Mon, 1 Apr 2019 15:25:07 +0000 (10:25 -0500)
committerGitHub <noreply@github.com>
Mon, 1 Apr 2019 15:25:07 +0000 (10:25 -0500)
Pim cleanup

47 files changed:
.dockerignore
.github/ISSUE_TEMPLATE.md [deleted file]
.github/ISSUE_TEMPLATE/bug_report.md [new file with mode: 0644]
.github/PULL_REQUEST_TEMPLATE.md [deleted file]
.github/PULL_REQUEST_TEMPLATE/pr.md [new file with mode: 0644]
README.md
alpine/APKBUILD.in
alpine/docker-start [deleted file]
bfdd/bfd.c
bfdd/ptm_adapter.c
bgpd/bgp_route.c
bgpd/bgp_vty.c
docker/alpine/Dockerfile
docker/alpine/alpine-build.sh [deleted file]
docker/alpine/build.sh
docker/alpine/builder [deleted file]
docker/alpine/docker-start [new file with mode: 0755]
isisd/isis_zebra.c
lib/zclient.c
nhrpd/nhrp_interface.c
ospf6d/ospf6_zebra.c
pimd/pim_cmd.c
pimd/pim_rp.c
pimd/pim_zebra.c
ripngd/ripng_zebra.c
tests/topotests/ldp-vpls-topo1/r1/zebra.conf
tests/topotests/ldp-vpls-topo1/r2/zebra.conf
tests/topotests/ldp-vpls-topo1/r3/zebra.conf
tests/topotests/lib/topogen.py
tests/topotests/lib/topotest.py
zebra/connected.c
zebra/debug.c
zebra/debug.h
zebra/main.c
zebra/rib.h
zebra/rt.h
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/zapi_msg.c
zebra/zebra_mpls.h
zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_rnh.h
zebra/zebra_router.c
zebra/zebra_vrf.c
zebra/zserv.c
zebra/zserv.h

index f2fc34583d3e482edd93929b2d7864e41fec56cd..d613e18dfc0ae1e810854a5396fccab3b5c08aa0 100644 (file)
@@ -5,3 +5,4 @@
 **/*.lo
 **/*.so
 **/.libs
+docker/alpine/pkgs
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644 (file)
index 62d3c23..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-# HOW TO GET YOUR ISSUE ADDRESSED FASTER
-
-* When reporting a crash provide a backtrace
-* When pasting configs, logs, shell output, backtraces, and other large chunks
-  of text [use Markdown code blocks](https://github.github.com/gfm/#fenced-code-blocks)
-* Include the FRR version; if you built from Git, please provide the commit
-  hash
-* Write your issue in English
-
-### 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/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644 (file)
index 0000000..1209f52
--- /dev/null
@@ -0,0 +1,43 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: triage
+assignees: ''
+
+---
+
+- When reporting a crash, provide a backtrace
+- When pasting configs, logs, shell output, backtraces, and other large chunks of text use Markdown code blocks
+- Include the FRR version; if you built from Git, please provide the commit hash
+- Write your issue in English
+
+---------------
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+(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?
+
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Versions**
+ - OS Kernel: [e.g. Linux, OpenBSD, etc] [version]
+ - FRR Version [version]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644 (file)
index 9f44f71..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-### Summary
-[fill here]
-
-### Related Issue
-[fill here if applicable]
-
-### Components
-[bgpd, build, doc, ripd, ospfd, eigrpd, isisd, etc. etc.]
diff --git a/.github/PULL_REQUEST_TEMPLATE/pr.md b/.github/PULL_REQUEST_TEMPLATE/pr.md
new file mode 100644 (file)
index 0000000..9f44f71
--- /dev/null
@@ -0,0 +1,8 @@
+### Summary
+[fill here]
+
+### Related Issue
+[fill here if applicable]
+
+### Components
+[bgpd, build, doc, ripd, ospfd, eigrpd, isisd, etc. etc.]
index 995c1b50ba9f26e94536182ad039936e286cd65c..a7725d5e4ed80f1c87f7384a405b40b913f6fd34 100644 (file)
--- a/README.md
+++ b/README.md
@@ -51,8 +51,9 @@ lists:
 | Users & Operators | frog@lists.frrouting.org     |
 | Announcements     | announce@lists.frrouting.org |
 
-For chat, we currently use [Slack](https://frrouting.slack.com). Please email
-the mailing list to request an invite as we do not issue automatic invites.
+For chat, we currently use [Slack](https://frrouting.slack.com). You can join
+by clicking the "Slack" link under the
+[Participate](https://frrouting.org/#participate) section of our website.
 
 
 Contributing
index 969b85f5240d52c6e14146a346dbed8ed7f6e184..0f56a427dd772990795911734ef1d891c6e13ea5 100644 (file)
@@ -9,13 +9,13 @@ license="GPL-2.0"
 depends="json-c c-ares ipsec-tools iproute2 python py-ipaddr bash"
 makedepends="ncurses-dev net-snmp-dev gawk texinfo perl
     acct autoconf automake bash
-    binutils binutils-libs bison bsd-compat-headers build-base
+    binutils bison bsd-compat-headers build-base
     c-ares c-ares-dev ca-certificates cryptsetup-libs curl
     device-mapper-libs expat fakeroot flex fortify-headers gdbm
     git gmp isl json-c-dev kmod lddtree libacl libatomic libattr
     libblkid libburn libbz2 libc-dev libcap libcurl libedit libffi libgcc
     libgomp libisoburn libisofs libltdl libressl libssh2
-    libstdc++ libtool libuuid linux-headers lzip lzo m4 make mkinitfs mpc1
+    libstdc++ libtool libuuid libyang-dev linux-headers lzip lzo m4 make mkinitfs mpc1
     mpfr3 mtools musl-dev ncurses-libs ncurses-terminfo ncurses-terminfo-base
     patch pax-utils pcre perl pkgconf python2 python2-dev readline
     readline-dev sqlite-libs squashfs-tools sudo tar texinfo xorriso xz-libs
@@ -23,7 +23,7 @@ makedepends="ncurses-dev net-snmp-dev gawk texinfo perl
 checkdepends="pytest py-setuptools"
 install="$pkgname.pre-install $pkgname.pre-deinstall $pkgname.post-deinstall"
 subpackages="$pkgname-dev $pkgname-doc $pkgname-dbg"
-source="$pkgname-$pkgver.tar.gz docker-start daemons"
+source="$pkgname-$pkgver.tar.gz"
 
 builddir="$srcdir"/$pkgname-$pkgver
 
@@ -60,8 +60,7 @@ package() {
        cd "$builddir"
        make DESTDIR="$pkgdir" install
 
-       install -Dm755 "$srcdir"/docker-start "$pkgdir"$_sbindir
-       install -Dm644 "$srcdir"/daemons "$pkgdir"$_sysconfdir
+       install -Dm644 "$builddir"/tools/etc/frr/daemons "$pkgdir"$_sysconfdir
        install -d "$pkgdir"/etc/init.d
        ln -s ${_sbindir}/frr "$pkgdir"/etc/init.d/frr
 }
diff --git a/alpine/docker-start b/alpine/docker-start
deleted file mode 100755 (executable)
index 43854ab..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-set -e
-
-##
-# For volume mounts...
-##
-chown -R frr:frr /etc/frr
-/etc/init.d/frr start
-exec sleep 10000d
index 3575ba7a008c9d5cb0af319f771bcf0d96e8cb15..e9645824f283d406de816b9d113388e50a7cabf9 100644 (file)
@@ -1180,6 +1180,9 @@ const char *bs_to_string(const struct bfd_session *bs)
        if (bs->key.ifname[0])
                pos += snprintf(buf + pos, sizeof(buf) - pos, " ifname:%s",
                                bs->key.ifname);
+
+       (void)pos;
+
        return buf;
 }
 
index b44d13f132a34b67df5216cccc19b8d3e587a4ab..8d80b9468db5374af1dbdeda8af84b00b05f9ff2 100644 (file)
@@ -613,6 +613,8 @@ static int bfdd_interface_update(int cmd, struct zclient *zc,
 
        bfdd_sessions_disable_interface(ifp);
 
+       if_set_index(ifp, IFINDEX_INTERNAL);
+
        return 0;
 }
 
index eca632dd448cf1601fb46375646f9682b686326b..ad9d22a7a5d332e281b2cec675c8696410872938 100644 (file)
@@ -10225,40 +10225,20 @@ ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
 }
 #endif
 
-static int bgp_table_stats_walker(struct thread *t)
+static void bgp_table_stats_rn(struct bgp_node *rn, struct bgp_node *top,
+                              struct bgp_table_stats *ts, unsigned int space)
 {
-       struct bgp_node *rn;
-       struct bgp_node *top;
-       struct bgp_table_stats *ts = THREAD_ARG(t);
-       unsigned int space = 0;
-
-       if (!(top = bgp_table_top(ts->table)))
-               return 0;
-
-       switch (top->p.family) {
-       case AF_INET:
-               space = IPV4_MAX_BITLEN;
-               break;
-       case AF_INET6:
-               space = IPV6_MAX_BITLEN;
-               break;
-       }
-
-       ts->counts[BGP_STATS_MAXBITLEN] = space;
-
-       for (rn = top; rn; rn = bgp_route_next(rn)) {
-               struct bgp_path_info *pi;
-               struct bgp_node *prn = bgp_node_parent_nolock(rn);
-               unsigned int pinum = 0;
+       struct bgp_node *prn = bgp_node_parent_nolock(rn);
+       struct bgp_path_info *pi;
 
-               if (rn == top)
-                       continue;
+       if (rn == top)
+               return;
 
-               if (!bgp_node_has_bgp_path_info_data(rn))
-                       continue;
+       if (!bgp_node_has_bgp_path_info_data(rn))
+               return;
 
-               ts->counts[BGP_STATS_PREFIXES]++;
-               ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
+       ts->counts[BGP_STATS_PREFIXES]++;
+       ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
 
 #if 0
       ts->counts[BGP_STATS_AVGPLEN]
@@ -10267,49 +10247,43 @@ static int bgp_table_stats_walker(struct thread *t)
                       rn->p.prefixlen);
 #endif
 
-               /* check if the prefix is included by any other announcements */
-               while (prn && !bgp_node_has_bgp_path_info_data(prn))
-                       prn = bgp_node_parent_nolock(prn);
+       /* check if the prefix is included by any other announcements */
+       while (prn && !bgp_node_has_bgp_path_info_data(prn))
+               prn = bgp_node_parent_nolock(prn);
 
-               if (prn == NULL || prn == top) {
-                       ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
-                       /* announced address space */
-                       if (space)
-                               ts->total_space +=
-                                       pow(2.0, space - rn->p.prefixlen);
-               } else if (bgp_node_has_bgp_path_info_data(prn))
-                       ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
+       if (prn == NULL || prn == top) {
+               ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
+               /* announced address space */
+               if (space)
+                       ts->total_space += pow(2.0, space - rn->p.prefixlen);
+       } else if (bgp_node_has_bgp_path_info_data(prn))
+               ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
 
-               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
-                       pinum++;
-                       ts->counts[BGP_STATS_RIB]++;
-
-                       if (pi->attr
-                           && (CHECK_FLAG(pi->attr->flag,
-                                          ATTR_FLAG_BIT(
-                                                  BGP_ATTR_ATOMIC_AGGREGATE))))
-                               ts->counts[BGP_STATS_AGGREGATES]++;
-
-                       /* as-path stats */
-                       if (pi->attr && pi->attr->aspath) {
-                               unsigned int hops =
-                                       aspath_count_hops(pi->attr->aspath);
-                               unsigned int size =
-                                       aspath_size(pi->attr->aspath);
-                               as_t highest = aspath_highest(pi->attr->aspath);
-
-                               ts->counts[BGP_STATS_ASPATH_COUNT]++;
-
-                               if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
-                                       ts->counts[BGP_STATS_ASPATH_MAXHOPS] =
-                                               hops;
-
-                               if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
-                                       ts->counts[BGP_STATS_ASPATH_MAXSIZE] =
-                                               size;
-
-                               ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
-                               ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
+
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
+               ts->counts[BGP_STATS_RIB]++;
+
+               if (pi->attr
+                   && (CHECK_FLAG(pi->attr->flag,
+                                  ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))))
+                       ts->counts[BGP_STATS_AGGREGATES]++;
+
+               /* as-path stats */
+               if (pi->attr && pi->attr->aspath) {
+                       unsigned int hops = aspath_count_hops(pi->attr->aspath);
+                       unsigned int size = aspath_size(pi->attr->aspath);
+                       as_t highest = aspath_highest(pi->attr->aspath);
+
+                       ts->counts[BGP_STATS_ASPATH_COUNT]++;
+
+                       if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
+                               ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
+
+                       if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
+                               ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
+
+                       ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
+                       ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
 #if 0
               ts->counts[BGP_STATS_ASPATH_AVGHOPS]
                 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
@@ -10320,12 +10294,52 @@ static int bgp_table_stats_walker(struct thread *t)
                               ts->counts[BGP_STATS_ASPATH_AVGSIZE],
                               size);
 #endif
-                               if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
-                                       ts->counts[BGP_STATS_ASN_HIGHEST] =
-                                               highest;
-                       }
+                       if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
+                               ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
                }
        }
+}
+
+static int bgp_table_stats_walker(struct thread *t)
+{
+       struct bgp_node *rn, *nrn;
+       struct bgp_node *top;
+       struct bgp_table_stats *ts = THREAD_ARG(t);
+       unsigned int space = 0;
+
+       if (!(top = bgp_table_top(ts->table)))
+               return 0;
+
+       switch (ts->table->afi) {
+       case AFI_IP:
+               space = IPV4_MAX_BITLEN;
+               break;
+       case AFI_IP6:
+               space = IPV6_MAX_BITLEN;
+               break;
+       default:
+               return 0;
+       }
+
+       ts->counts[BGP_STATS_MAXBITLEN] = space;
+
+       for (rn = top; rn; rn = bgp_route_next(rn)) {
+               if (ts->table->safi == SAFI_MPLS_VPN) {
+                       struct bgp_table *table;
+
+                       table = bgp_node_get_bgp_table_info(rn);
+                       if (!table)
+                               continue;
+
+                       top = bgp_table_top(table);
+                       for (nrn = bgp_table_top(table); nrn;
+                            nrn = bgp_route_next(nrn))
+                               bgp_table_stats_rn(nrn, top, ts, space);
+               } else {
+                       bgp_table_stats_rn(rn, top, ts, space);
+               }
+       }
+
        return 0;
 }
 
@@ -10774,7 +10788,11 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                return;
        }
 
-       table = bgp->rib[afi][safi];
+       /* labeled-unicast routes live in the unicast table */
+       if (safi == SAFI_LABELED_UNICAST)
+               table = bgp->rib[afi][SAFI_UNICAST];
+       else
+               table = bgp->rib[afi][safi];
 
        output_count = filtered_count = 0;
        subgrp = peer_subgroup(peer, afi, safi);
@@ -11028,10 +11046,6 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
        if (use_json)
                json = json_object_new_object();
 
-       /* labeled-unicast routes live in the unicast table */
-       if (safi == SAFI_LABELED_UNICAST)
-               safi = SAFI_UNICAST;
-
        if (!peer || !peer->afc[afi][safi]) {
                if (use_json) {
                        json_object_string_add(
index 5350ebeec7c7a13cf2dcd3b2f28d07da509486c9..9004926dee5edb5dcf9cdd821365b9999cd16fd5 100644 (file)
@@ -771,19 +771,23 @@ static int bgp_clear_vty(struct vty *vty, const char *name, afi_t afi,
 /* clear soft inbound */
 static void bgp_clear_star_soft_in(struct vty *vty, const char *name)
 {
-       bgp_clear_vty(vty, name, AFI_IP, SAFI_UNICAST, clear_all,
-                     BGP_CLEAR_SOFT_IN, NULL);
-       bgp_clear_vty(vty, name, AFI_IP6, SAFI_UNICAST, clear_all,
-                     BGP_CLEAR_SOFT_IN, NULL);
+       afi_t afi;
+       safi_t safi;
+
+       FOREACH_AFI_SAFI (afi, safi)
+               bgp_clear_vty(vty, name, afi, safi, clear_all,
+                             BGP_CLEAR_SOFT_IN, NULL);
 }
 
 /* clear soft outbound */
 static void bgp_clear_star_soft_out(struct vty *vty, const char *name)
 {
-       bgp_clear_vty(vty, name, AFI_IP, SAFI_UNICAST, clear_all,
-                     BGP_CLEAR_SOFT_OUT, NULL);
-       bgp_clear_vty(vty, name, AFI_IP6, SAFI_UNICAST, clear_all,
-                     BGP_CLEAR_SOFT_OUT, NULL);
+       afi_t afi;
+       safi_t safi;
+
+       FOREACH_AFI_SAFI (afi, safi)
+               bgp_clear_vty(vty, name, afi, safi, clear_all,
+                             BGP_CLEAR_SOFT_OUT, NULL);
 }
 
 
index dd29358b07368e78ab625d79291fc8e979a60e3d..815983a3940a195b03a04aadc1e7ef61795c8aac 100644 (file)
@@ -1,35 +1,58 @@
-FROM alpine:3.7 as source-builder
-ARG commit
-RUN apk add --no-cache abuild acct alpine-sdk attr autoconf automake bash \
-    binutils binutils-libs bison bsd-compat-headers build-base \
-    c-ares c-ares-dev ca-certificates cryptsetup-libs curl \
-    device-mapper-libs expat fakeroot flex fortify-headers g++ gcc gdbm \
-    git gmp isl json-c json-c-dev kmod lddtree libacl libatomic libattr \
-    libblkid libburn libbz2 libc-dev libcap libcurl libedit libffi libgcc \
-    libgomp libisoburn libisofs libltdl libressl libssh2 \
-    libstdc++ libtool libuuid linux-headers lzip lzo m4 make mkinitfs mpc1 \
-    mpfr3 mtools musl-dev ncurses-libs ncurses-terminfo ncurses-terminfo-base \
-    patch pax-utils pcre perl pkgconf python2 python2-dev readline \
-    readline-dev sqlite-libs squashfs-tools sudo tar texinfo xorriso xz-libs \
-    groff gzip bc py-sphinx
-ADD . /src
-RUN (cd /src && \
-       ./bootstrap.sh && \
-       ./configure \
+# This stage builds a dist tarball from the source
+FROM alpine:edge as source-builder
+
+RUN mkdir -p /src/alpine
+COPY alpine/APKBUILD.in /src/alpine
+RUN source /src/alpine/APKBUILD.in \
+       && echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories \
+       && apk add \
+               --no-cache \
+               --update-cache \
+               $makedepends \
+               gzip
+
+COPY . /src
+ARG PKGVER
+RUN cd /src \
+       && ./bootstrap.sh \
+       && ./configure \
                --enable-numeric-version \
-               --with-pkg-extra-version=_git$commit && \
-       make dist)
-FROM alpine:3.7 as alpine-builder
-RUN apk add --no-cache abuild alpine-sdk && mkdir -p /pkgs/apk
-ADD docker/alpine/alpine-build.sh /usr/bin/
-ADD docker/alpine/builder /etc/sudoers.d
-COPY --from=source-builder /src/*.tar.gz /src/alpine/* /src/tools/etc/frr/daemons* /dist/
+               --with-pkg-extra-version="_git$PKGVER" \
+       && make dist
+
+# This stage builds an apk from the dist tarball
+FROM alpine:edge as alpine-builder
+# Don't use nocache here so that abuild can use the cache
+RUN echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories \
+       && apk add \
+               --update-cache \
+               abuild \
+               alpine-conf \
+               alpine-sdk \
+       && setup-apkcache /var/cache/apk \
+       && mkdir -p /pkgs/apk \
+       && echo 'builder ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
+
+COPY --from=source-builder /src/frr-*.tar.gz /src/alpine/* /dist/
 RUN adduser -D -G abuild builder && chown -R builder /dist /pkgs
 USER builder
-RUN /usr/bin/alpine-build.sh
-FROM alpine:3.7
+RUN cd /dist \
+       && abuild-keygen -a -n \
+       && abuild checksum \
+       && abuild -r -P /pkgs/apk
+
+# This stage installs frr from the apk
+FROM alpine:edge
 RUN mkdir -p /pkgs/apk
 COPY --from=alpine-builder /pkgs/apk/ /pkgs/apk/
-RUN apk add --no-cache tini
-RUN apk add --no-cache --allow-untrusted /pkgs/apk/x86_64/*.apk
+RUN echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories \
+       && apk add \
+               --no-cache \
+               --update-cache \
+               tini \
+       && apk add \
+               --no-cache \
+               --allow-untrusted /pkgs/apk/*/*.apk \
+       && rm -rf /pkgs
+COPY docker/alpine/docker-start /usr/lib/frr/docker-start
 ENTRYPOINT [ "/sbin/tini", "--", "/usr/lib/frr/docker-start" ]
diff --git a/docker/alpine/alpine-build.sh b/docker/alpine/alpine-build.sh
deleted file mode 100755 (executable)
index d4c0311..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-set -e
-
-cd /dist
-
-sudo apk --update add alpine-conf
-sudo setup-apkcache /var/cache/apk
-abuild-keygen -a -n
-abuild checksum
-abuild -r -P /pkgs/apk
index 40ed1194fe6cb23514352d146a30ec2f689b6f0c..22a36877c039d1f0f4301d86a05704b1845b0690 100755 (executable)
@@ -1,17 +1,30 @@
 #!/bin/sh
 
 set -e
-set -v
 set -x
 
 ##
-# commit must be converted to decimal
+# Package version needs to be decimal
 ##
-c=`git rev-parse --short=10 HEAD`
-commit=`printf '%u\n' 0x$c`
-docker build -f docker/alpine/Dockerfile \
-       --build-arg commit=$commit -t frr:alpine-$c .
-id=`docker create frr:alpine-$c`
-docker cp ${id}:/pkgs/ docker
-docker rm $id
-docker rmi frr:alpine-$c
+GITREV="$(git rev-parse --short=10 HEAD)"
+PKGVER="$(printf '%u\n' 0x$GITREV)"
+
+docker build \
+       --pull \
+       --file=docker/alpine/Dockerfile \
+       --build-arg="PKGVER=$PKGVER" \
+       --tag="frr:alpine-builder-$GITREV" \
+       --target=alpine-builder \
+       .
+
+CONTAINER_ID="$(docker create "frr:alpine-builder-$GITREV")"
+docker cp "${CONTAINER_ID}:/pkgs/" docker/alpine
+docker rm "${CONTAINER_ID}"
+
+docker build \
+       --file=docker/alpine/Dockerfile \
+       --build-arg="PKGVER=$PKGVER" \
+       --tag="frr:alpine-$GITREV" \
+       .
+
+docker rmi "frr:alpine-builder-$GITREV"
diff --git a/docker/alpine/builder b/docker/alpine/builder
deleted file mode 100644 (file)
index a950b8a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-builder ALL=(ALL) NOPASSWD:ALL
diff --git a/docker/alpine/docker-start b/docker/alpine/docker-start
new file mode 100755 (executable)
index 0000000..52cfb66
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+set -e
+
+##
+# For volume mounts...
+##
+chown -R frr:frr /etc/frr
+/usr/lib/frr/frrinit.sh start
+
+# Sleep forever
+exec tail -f /dev/null
index dfe74e325ed0f2831b0e5c303c3d2ae63ac5b2b3..79d79f8911647653be9c590c00fe21dc7235f15b 100644 (file)
@@ -362,6 +362,10 @@ static int isis_zebra_read(int command, struct zclient *zclient,
        if (zapi_route_decode(zclient->ibuf, &api) < 0)
                return -1;
 
+       if (api.prefix.family == AF_INET6
+           && IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
+               return 0;
+
        /*
         * Avoid advertising a false default reachability. (A default
         * route installed by IS-IS gets redistributed from zebra back
index 7b94f1d907a3e80d61c7cef3a6991b95fff688ae..3e26cd9e6c42cc512ce821b03610901e449b17b6 100644 (file)
@@ -414,6 +414,9 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
        /* We need router-id information. */
        zebra_message_send(zclient, ZEBRA_ROUTER_ID_ADD, vrf_id);
 
+       /* We need interface information. */
+       zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id);
+
        /* Set unwanted redistribute route. */
        for (afi = AFI_IP; afi < AFI_MAX; afi++)
                vrf_bitmap_set(zclient->redist[afi][zclient->redist_default],
@@ -478,6 +481,8 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
        /* We need router-id information. */
        zebra_message_send(zclient, ZEBRA_ROUTER_ID_DELETE, vrf_id);
 
+       zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id);
+
        /* Set unwanted redistribute route. */
        for (afi = AFI_IP; afi < AFI_MAX; afi++)
                vrf_bitmap_unset(zclient->redist[afi][zclient->redist_default],
index ccca100db57940b038501c5a08b44cccd3958e20..b33eaa047849e38bad0f6c4e36be90aa5cce105e 100644 (file)
@@ -327,9 +327,11 @@ int nhrp_interface_delete(int cmd, struct zclient *client, zebra_size_t length,
                return 0;
 
        debugf(NHRP_DEBUG_IF, "if-delete: %s", ifp->name);
-       if_set_index(ifp, ifp->ifindex);
+
        nhrp_interface_update(ifp);
-       /* if_delete(ifp); */
+
+       if_set_index(ifp, IFINDEX_INTERNAL);
+
        return 0;
 }
 
index 54f1735e7acc6652ba747695a0e96af0a8b8aab4..abdc82a73841983085325bf3f5456aca87e4c217 100644 (file)
@@ -226,6 +226,9 @@ static int ospf6_zebra_read_route(int command, struct zclient *zclient,
        if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
                return 0;
 
+       if (IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
+               return 0;
+
        ifindex = api.nexthops[0].ifindex;
        nexthop = &api.nexthops[0].gate.ipv6;
 
index f058b7adbfb26ffbe7c62fcbe94b7b188fb24fc9..f9140802fbb07545d9447b289f040443ac490232 100644 (file)
@@ -198,7 +198,7 @@ static void pim_show_assert_helper(struct vty *vty,
        pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
        pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer);
 
-       vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
+       vty_out(vty, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
                ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
                pim_ifchannel_ifassert_name(ch->ifassert_state), winner_str,
                uptime, timer);
@@ -214,7 +214,7 @@ static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
        now = pim_time_monotonic_sec();
 
        vty_out(vty,
-               "Interface Address         Source          Group           State  Winner          Uptime   Timer\n");
+               "Interface        Address         Source          Group           State  Winner          Uptime   Timer\n");
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
                pim_ifp = ifp->info;
@@ -239,7 +239,7 @@ static void pim_show_assert_internal_helper(struct vty *vty,
 
        pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
        pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
-       vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
+       vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
                ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
                PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
                pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
@@ -261,7 +261,7 @@ static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
                "eATD: Evaluate AssertTrackingDesired\n\n");
 
        vty_out(vty,
-               "Interface Address         Source          Group           CA  eCA ATD eATD\n");
+               "Interface        Address         Source          Group           CA  eCA ATD eATD\n");
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
                pim_ifp = ifp->info;
                if (!pim_ifp)
@@ -292,7 +292,7 @@ static void pim_show_assert_metric_helper(struct vty *vty,
        pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
        pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str));
 
-       vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
+       vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
                ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
                am.rpt_bit_flag ? "yes" : "no", am.metric_preference,
                am.route_metric, addr_str);
@@ -305,7 +305,7 @@ static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
        struct interface *ifp;
 
        vty_out(vty,
-               "Interface Address         Source          Group           RPT Pref Metric Address        \n");
+               "Interface        Address         Source          Group           RPT Pref Metric Address        \n");
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
                pim_ifp = ifp->info;
@@ -349,7 +349,7 @@ static void pim_show_assert_winner_metric_helper(struct vty *vty,
        else
                snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
 
-       vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
+       vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
                ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
                am->rpt_bit_flag ? "yes" : "no", pref_str, metr_str, addr_str);
 }
@@ -362,7 +362,7 @@ static void pim_show_assert_winner_metric(struct pim_instance *pim,
        struct interface *ifp;
 
        vty_out(vty,
-               "Interface Address         Source          Group           RPT Pref Metric Address        \n");
+               "Interface        Address         Source          Group           RPT Pref Metric Address        \n");
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
                pim_ifp = ifp->info;
@@ -462,7 +462,7 @@ static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
                                             json, JSON_C_TO_STRING_PRETTY));
        } else {
                vty_out(vty,
-                       "Interface  Address          Source           Group            Membership\n");
+                       "Interface         Address          Source           Group            Membership\n");
 
                /*
                 * Example of the json data we are traversing
@@ -499,7 +499,7 @@ static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
                                type = json_object_get_type(if_field_val);
 
                                if (type == json_type_object) {
-                                       vty_out(vty, "%-9s  ", key);
+                                       vty_out(vty, "%-16s  ", key);
 
                                        json_object_object_get_ex(
                                                val, "address", &json_tmp);
@@ -566,7 +566,7 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
                json = json_object_new_object();
        else
                vty_out(vty,
-                       "Interface  State          Address  V  Querier  Query Timer    Uptime\n");
+                       "Interface         State          Address  V  Querier  Query Timer    Uptime\n");
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
                struct pim_interface *pim_ifp;
@@ -614,7 +614,7 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
                                }
                        } else {
                                vty_out(vty,
-                                       "%-9s  %5s  %15s  %d  %7s  %11s  %8s\n",
+                                       "%-16s  %5s  %15s  %d  %7s  %11s  %8s\n",
                                        ifp->name,
                                        if_is_up(ifp)
                                                ? (igmp->mtrace_only ? "mtrc"
@@ -854,7 +854,7 @@ static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty)
        now = pim_time_monotonic_sec();
 
        vty_out(vty,
-               "Interface Address         Source          Group           Socket Uptime  \n");
+               "Interface        Address         Source          Group           Socket Uptime  \n");
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
                struct pim_interface *pim_ifp;
@@ -888,7 +888,7 @@ static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty)
                        pim_inet4_dump("<src?>", ij->source_addr, source_str,
                                       sizeof(source_str));
 
-                       vty_out(vty, "%-9s %-15s %-15s %-15s %6d %8s\n",
+                       vty_out(vty, "%-16s %-15s %-15s %-15s %6d %8s\n",
                                ifp->name, pri_addr_str, source_str, group_str,
                                ij->sock_fd, uptime);
                } /* for (pim_ifp->igmp_join_list) */
@@ -1421,11 +1421,11 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
                                             json, JSON_C_TO_STRING_PRETTY));
        } else {
                vty_out(vty,
-                       "Interface  State          Address  PIM Nbrs           PIM DR  FHR IfChannels\n");
+                       "Interface         State          Address  PIM Nbrs           PIM DR  FHR IfChannels\n");
 
                json_object_object_foreach(json, key, val)
                {
-                       vty_out(vty, "%-9s  ", key);
+                       vty_out(vty, "%-16s  ", key);
 
                        json_object_object_get_ex(val, "state", &json_tmp);
                        vty_out(vty, "%5s  ", json_object_get_string(json_tmp));
@@ -1474,12 +1474,13 @@ static void pim_show_interface_traffic(struct pim_instance *pim,
                json = json_object_new_object();
        else {
                vty_out(vty, "\n");
-               vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
-                       "Interface", "    HELLO", "    JOIN", "   PRUNE",
-                       "   REGISTER", "  REGISTER-STOP", "  ASSERT");
-               vty_out(vty, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
-                       "      Rx/Tx", "     Rx/Tx", "    Rx/Tx", "    Rx/Tx",
-                       "     Rx/Tx", "    Rx/Tx");
+               vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
+                       "Interface", "       HELLO", "       JOIN",
+                       "      PRUNE", "   REGISTER", "REGISTER-STOP",
+                       "  ASSERT");
+               vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
+                       "       Rx/Tx", "       Rx/Tx", "      Rx/Tx",
+                       "     Rx/Tx", "    Rx/Tx", "   Rx/Tx");
                vty_out(vty,
                        "---------------------------------------------------------------------------------------------------------------\n");
        }
@@ -1519,7 +1520,7 @@ static void pim_show_interface_traffic(struct pim_instance *pim,
                        json_object_object_add(json, ifp->name, json_row);
                } else {
                        vty_out(vty,
-                               "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
+                               "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
                                ifp->name, pim_ifp->pim_ifstat_hello_recv,
                                pim_ifp->pim_ifstat_hello_sent,
                                pim_ifp->pim_ifstat_join_recv,
@@ -1555,14 +1556,14 @@ static void pim_show_interface_traffic_single(struct pim_instance *pim,
                json = json_object_new_object();
        else {
                vty_out(vty, "\n");
-               vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
+               vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
                        "Interface", "    HELLO", "    JOIN", "   PRUNE",
                        "   REGISTER", "  REGISTER-STOP", "  ASSERT");
-               vty_out(vty, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
+               vty_out(vty, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
                        "      Rx/Tx", "     Rx/Tx", "    Rx/Tx", "    Rx/Tx",
                        "     Rx/Tx", "    Rx/Tx");
                vty_out(vty,
-                       "---------------------------------------------------------------------------------------------------------------\n");
+                       "---------------------------------------------------------------------------------------------------------------------\n");
        }
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -1605,7 +1606,7 @@ static void pim_show_interface_traffic_single(struct pim_instance *pim,
                        json_object_object_add(json, ifp->name, json_row);
                } else {
                        vty_out(vty,
-                               "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
+                               "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
                                ifp->name, pim_ifp->pim_ifstat_hello_recv,
                                pim_ifp->pim_ifstat_hello_sent,
                                pim_ifp->pim_ifstat_join_recv,
@@ -1687,7 +1688,7 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
                } else
                        json_object_object_add(json_grp, ch_src_str, json_row);
        } else {
-               vty_out(vty, "%-9s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
+               vty_out(vty, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
                        ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
                        ch_grp_str,
                        pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
@@ -1709,7 +1710,7 @@ static void pim_show_join(struct pim_instance *pim, struct vty *vty, bool uj)
                json = json_object_new_object();
        else
                vty_out(vty,
-                       "Interface Address         Source          Group           State      Uptime   Expire Prune\n");
+                       "Interface        Address         Source          Group           State      Uptime   Expire Prune\n");
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
                pim_ifp = ifp->info;
@@ -1957,7 +1958,7 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty,
                vty_out(vty,
                        "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
                vty_out(vty,
-                       "\nInstalled Source           Group            IIF      OIL\n");
+                       "\nInstalled Source           Group            IIF               OIL\n");
        }
 
        for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
@@ -2040,9 +2041,8 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty,
                                                    c_oil->cc.wrong_if);
                        }
                } else {
-                       vty_out(vty, "%-9d %-15s  %-15s  %-7s  ",
-                               c_oil->installed, src_str, grp_str,
-                               in_ifname);
+                       vty_out(vty, "%-9d %-15s  %-15s  %-16s  ",
+                               c_oil->installed, src_str, grp_str, in_ifname);
                }
 
                for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
@@ -2159,7 +2159,7 @@ static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
                json = json_object_new_object();
        } else {
                vty_out(vty,
-                       "Interface         Neighbor    Uptime  Holdtime  DR Pri\n");
+                       "Interface                Neighbor    Uptime  Holdtime  DR Pri\n");
        }
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -2201,7 +2201,7 @@ static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
                                                       neigh_src_str, json_row);
 
                        } else {
-                               vty_out(vty, "%-9s  %15s  %8s  %8s  %6d\n",
+                               vty_out(vty, "%-16s  %15s  %8s  %8s  %6d\n",
                                        ifp->name, neigh_src_str, uptime,
                                        expire, neigh->dr_priority);
                        }
@@ -2226,7 +2226,7 @@ static void pim_show_neighbors_secondary(struct pim_instance *pim,
        struct interface *ifp;
 
        vty_out(vty,
-               "Interface Address         Neighbor        Secondary      \n");
+               "Interface        Address         Neighbor        Secondary      \n");
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
                struct pim_interface *pim_ifp;
@@ -2263,7 +2263,7 @@ static void pim_show_neighbors_secondary(struct pim_instance *pim,
                                prefix2str(p, neigh_sec_str,
                                           sizeof(neigh_sec_str));
 
-                               vty_out(vty, "%-9s %-15s %-15s %-15s\n",
+                               vty_out(vty, "%-16s %-15s %-15s %-15s\n",
                                        ifp->name, inet_ntoa(ifaddr),
                                        neigh_src_str, neigh_sec_str);
                        }
@@ -2350,7 +2350,7 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
                json = json_object_new_object();
        else
                vty_out(vty,
-                       "Iif       Source          Group           State       Uptime   JoinTimer RSTimer   KATimer   RefCnt\n");
+                       "Iif             Source          Group           State       Uptime   JoinTimer RSTimer   KATimer   RefCnt\n");
 
        for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
                char src_str[INET_ADDRSTRLEN];
@@ -2465,7 +2465,7 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
                        json_object_object_add(json_group, src_str, json_row);
                } else {
                        vty_out(vty,
-                               "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
+                               "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
                                up->rpf.source_nexthop.interface
                                    ? up->rpf.source_nexthop.interface->name
                                    : "Unknown",
@@ -2527,7 +2527,7 @@ static void pim_show_join_desired_helper(struct pim_instance *pim,
                json_object_object_add(json_group, src_str, json_row);
 
        } else {
-               vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
+               vty_out(vty, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
                        ch->interface->name, src_str, grp_str,
                        pim_macro_ch_lost_assert(ch) ? "yes" : "no",
                        pim_macro_chisin_joins(ch) ? "yes" : "no",
@@ -2553,7 +2553,7 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
                json = json_object_new_object();
        else
                vty_out(vty,
-                       "Interface Source          Group           LostAssert Joins PimInclude JoinDesired EvalJD\n");
+                       "Interface        Source          Group           LostAssert Joins PimInclude JoinDesired EvalJD\n");
 
        /* scan per-interface (S,G) state */
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -2589,7 +2589,7 @@ static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
                json = json_object_new_object();
        else
                vty_out(vty,
-                       "Source          Group           RpfIface RibNextHop      RpfAddress     \n");
+                       "Source          Group           RpfIface         RibNextHop      RpfAddress     \n");
 
        for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
                char src_str[INET_ADDRSTRLEN];
@@ -2632,7 +2632,7 @@ static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
                                               rpf_addr_str);
                        json_object_object_add(json_group, src_str, json_row);
                } else {
-                       vty_out(vty, "%-15s %-15s %-8s %-15s %-15s\n", src_str,
+                       vty_out(vty, "%-15s %-15s %-16s %-15s %-15s\n", src_str,
                                grp_str, rpf_ifname, rpf_nexthop_str,
                                rpf_addr_str);
                }
@@ -2726,7 +2726,7 @@ static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
                show_rpf_refresh_stats(vty, pim, now, json);
                vty_out(vty, "\n");
                vty_out(vty,
-                       "Source          Group           RpfIface RpfAddress      RibNextHop      Metric Pref\n");
+                       "Source          Group           RpfIface         RpfAddress      RibNextHop      Metric Pref\n");
        }
 
        for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
@@ -2774,7 +2774,7 @@ static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
                        json_object_object_add(json_group, src_str, json_row);
 
                } else {
-                       vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
+                       vty_out(vty, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
                                src_str, grp_str, rpf_ifname, rpf_addr_str,
                                rib_nexthop_str,
                                rpf->source_nexthop.mrib_route_metric,
@@ -2809,7 +2809,7 @@ static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
                ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
 
                vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
-               vty_out(vty, "%-14s ", ifp ? ifp->name : "NULL");
+               vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
                vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
                vty_out(vty, "\n");
        }
@@ -2824,8 +2824,8 @@ static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
        cwd.pim = pim;
        vty_out(vty, "Number of registered addresses: %lu\n",
                pim->rpf_hash->count);
-       vty_out(vty, "Address         Interface      Nexthop\n");
-       vty_out(vty, "-------------------------------------------\n");
+       vty_out(vty, "Address         Interface        Nexthop\n");
+       vty_out(vty, "---------------------------------------------\n");
 
        hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
 }
@@ -2844,7 +2844,7 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
                json = json_object_new_object();
        else
                vty_out(vty,
-                       "Interface Address         Group           Mode Timer    Srcs V Uptime  \n");
+                       "Interface        Address         Group           Mode Timer    Srcs V Uptime  \n");
 
        /* scan interfaces */
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -2924,7 +2924,7 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
 
                                } else {
                                        vty_out(vty,
-                                               "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
+                                               "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
                                                ifp->name, ifaddr_str,
                                                group_str,
                                                grp->igmp_version == 3
@@ -2956,7 +2956,7 @@ static void igmp_show_group_retransmission(struct pim_instance *pim,
        struct interface *ifp;
 
        vty_out(vty,
-               "Interface Address         Group           RetTimer Counter RetSrcs\n");
+               "Interface        Address         Group           RetTimer Counter RetSrcs\n");
 
        /* scan interfaces */
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -3004,7 +3004,7 @@ static void igmp_show_group_retransmission(struct pim_instance *pim,
                                        }
                                }
 
-                               vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d\n",
+                               vty_out(vty, "%-16s %-15s %-15s %-8s %7d %7d\n",
                                        ifp->name, ifaddr_str, group_str,
                                        grp_retr_mmss,
                                        grp->group_specific_query_retransmit_count,
@@ -3023,7 +3023,7 @@ static void igmp_show_sources(struct pim_instance *pim, struct vty *vty)
        now = pim_time_monotonic_sec();
 
        vty_out(vty,
-               "Interface Address         Group           Source          Timer Fwd Uptime  \n");
+               "Interface        Address         Group           Source          Timer Fwd Uptime  \n");
 
        /* scan interfaces */
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -3075,7 +3075,7 @@ static void igmp_show_sources(struct pim_instance *pim, struct vty *vty)
                                                now - src->source_creation);
 
                                        vty_out(vty,
-                                               "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
+                                               "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
                                                ifp->name, ifaddr_str,
                                                group_str, source_str, mmss,
                                                IGMP_SOURCE_TEST_FORWARDING(
@@ -3096,7 +3096,7 @@ static void igmp_show_source_retransmission(struct pim_instance *pim,
        struct interface *ifp;
 
        vty_out(vty,
-               "Interface Address         Group           Source          Counter\n");
+               "Interface        Address         Group           Source          Counter\n");
 
        /* scan interfaces */
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -3138,7 +3138,7 @@ static void igmp_show_source_retransmission(struct pim_instance *pim,
                                                source_str, sizeof(source_str));
 
                                        vty_out(vty,
-                                               "%-9s %-15s %-15s %-15s %7d\n",
+                                               "%-16s %-15s %-15s %-15s %7d\n",
                                                ifp->name, ifaddr_str,
                                                group_str, source_str,
                                                src->source_query_retransmit_count);
@@ -4378,7 +4378,7 @@ static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty)
        vty_out(vty, "\n");
 
        vty_out(vty,
-               "Interface Address            ifi Vif  PktsIn PktsOut    BytesIn   BytesOut\n");
+               "Interface        Address            ifi Vif  PktsIn PktsOut    BytesIn   BytesOut\n");
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
                struct pim_interface *pim_ifp;
@@ -4403,7 +4403,7 @@ static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty)
 
                ifaddr = pim_ifp->primary_address;
 
-               vty_out(vty, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
+               vty_out(vty, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
                        ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
                        pim_ifp->mroute_vif_index, (unsigned long)vreq.icount,
                        (unsigned long)vreq.ocount, (unsigned long)vreq.ibytes,
@@ -4532,7 +4532,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill,
                json = json_object_new_object();
        } else {
                vty_out(vty,
-                       "Source          Group           Proto  Input      Output     TTL  Uptime\n");
+                       "Source          Group           Proto  Input            Output           TTL  Uptime\n");
        }
 
        now = pim_time_monotonic_sec();
@@ -4682,7 +4682,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill,
                                }
 
                                vty_out(vty,
-                                       "%-15s %-15s %-6s %-10s %-10s %-3d  %8s\n",
+                                       "%-15s %-15s %-6s %-16s %-16s %-3d  %8s\n",
                                        src_str, grp_str, proto, in_ifname,
                                        out_ifname, ttl, oif_uptime);
 
@@ -4696,7 +4696,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill,
                }
 
                if (!uj && !found_oif) {
-                       vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d  %8s\n",
+                       vty_out(vty, "%-15s %-15s %-6s %-16s %-16s %-3d  %8s\n",
                                src_str, grp_str, "none", in_ifname, "none", 0,
                                "--:--:--");
                }
@@ -4803,7 +4803,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill,
                                                       json_ifp_out);
                        } else {
                                vty_out(vty,
-                                       "%-15s %-15s %-6s %-10s %-10s %-3d  %8s %s\n",
+                                       "%-15s %-15s %-6s %-16s %-16s %-3d  %8s %s\n",
                                        src_str, grp_str, proto, in_ifname,
                                        out_ifname, ttl, oif_uptime,
                                        pim->vrf->name);
@@ -4818,7 +4818,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill,
 
                if (!uj && !found_oif) {
                        vty_out(vty,
-                               "%-15s %-15s %-6s %-10s %-10s %-3d  %8s %s\n",
+                               "%-15s %-15s %-6s %-16s %-16s %-3d  %8s %s\n",
                                src_str, grp_str, proto, in_ifname, "none", 0,
                                "--:--:--", pim->vrf->name);
                }
index 0a98a2f7e90acbee061da0339d762e53928a0ace..b7db7d04187fc100ea57bca967a873f6eb68b2f2 100644 (file)
@@ -1114,7 +1114,7 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
                json = json_object_new_object();
        else
                vty_out(vty,
-                       "RP address       group/prefix-list   OIF         I am RP\n");
+                       "RP address       group/prefix-list   OIF               I am RP\n");
 
        for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) {
                if (!pim_rpf_addr_is_inaddr_none(&rp_info->rp)) {
@@ -1177,11 +1177,11 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
                                                           48));
 
                                if (rp_info->rp.source_nexthop.interface)
-                                       vty_out(vty, "%-10s  ",
+                                       vty_out(vty, "%-16s  ",
                                                rp_info->rp.source_nexthop
                                                        .interface->name);
                                else
-                                       vty_out(vty, "%-10s  ", "(Unknown)");
+                                       vty_out(vty, "%-16s  ", "(Unknown)");
 
                                if (rp_info->i_am_rp)
                                        vty_out(vty, "yes\n");
index a27722688560207045f8207619dfc68e23299715..70f099b0d78d2c73b24bf53efd9b04ceb736d079 100644 (file)
@@ -150,6 +150,8 @@ static int pim_zebra_if_del(int command, struct zclient *zclient,
        if (!if_is_operative(ifp))
                pim_if_addr_del_all(ifp);
 
+       if_set_index(ifp, IFINDEX_INTERNAL);
+
        return 0;
 }
 
index 28a57f25d007bbbcf6814d82e733df6d92b50f98..c68c066f0cbee94da2864475911740ab460a1d3b 100644 (file)
@@ -126,6 +126,9 @@ static int ripng_zebra_read_route(int command, struct zclient *zclient,
        if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
                return 0;
 
+       if (IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
+               return 0;
+
        nexthop = api.nexthops[0].gate.ipv6;
        ifindex = api.nexthops[0].ifindex;
 
index d0ec9f5d75988210e2780389116b85f2686ed91c..edfa1780a946e42a38d7ef91d8cd30cab5457e8e 100644 (file)
@@ -2,10 +2,12 @@ log file zebra.log
 !
 hostname r1
 !
-debug zebra rib
+debug zebra kernel
+debug zebra rib detailed
+debug zebra dplane detailed
 debug zebra nht
 debug zebra pseudowires
-debug zebra packet
+debug zebra mpls
 !
 interface lo
  ip address 1.1.1.1/32
index 8bd800714c2a6af8e2f3f464e588bc44b881c05d..6b95efdce8c2e88eea4476a7fa6b4f4b6fbc5d60 100644 (file)
@@ -2,10 +2,11 @@ log file zebra.log
 !
 hostname r2
 !
-debug zebra rib
+debug zebra rib detailed
+debug zebra dplane detailed
+debug zebra kernel
 debug zebra nht
 debug zebra pseudowires
-debug zebra packet
 !
 interface lo
  ip address 2.2.2.2/32
index 2ff61365b5e20084ebac6a1202d3e9d33542539e..85ec68ff32bbdbbda52f033e6aeb632f27aad24f 100644 (file)
@@ -2,10 +2,11 @@ log file zebra.log
 !
 hostname r3
 !
-debug zebra rib
+debug zebra rib detailed
+debug zebra dplane detailed
+debug zebra kernel
 debug zebra nht
 debug zebra pseudowires
-debug zebra packet
 !
 interface lo
  ip address 3.3.3.3/32
index 8688a13aef16b8f0dfcd0508aa9b22f252a1f692..d989240a162ba91349620d5247cc36f4a90b9d6a 100644 (file)
@@ -586,9 +586,9 @@ class TopoRouter(TopoGear):
         os.system('chmod -R go+rw /tmp/topotests')
 
         # Open router log file
-        logfile = '{0}/{1}.log'.format(dir, name)
-
+        logfile = '{0}/{1}.log'.format(self.logdir, name)
         self.logger = logger_config.get_logger(name=name, target=logfile)
+
         self.tgen.topo.addNode(self.name, cls=self.cls, **params)
 
     def __str__(self):
index 84358b94bc2b29171f167308746b1a150f612966..e0da20e07f506d95d37479b422f7b497f3665c4c 100644 (file)
@@ -63,23 +63,6 @@ class json_cmp_result(object):
     def __str__(self):
         return '\n'.join(self.errors)
 
-def get_test_logdir(node=None, init=False):
-    """
-    Return the current test log directory based on PYTEST_CURRENT_TEST
-    environment variable.
-    Optional paramters:
-    node:  when set, adds the node specific log directory to the init dir
-    init:  when set, initializes the log directory and fixes path permissions
-    """
-    cur_test = os.environ['PYTEST_CURRENT_TEST']
-
-    ret = '/tmp/topotests/' + cur_test[0:cur_test.find(".py")].replace('/','.')
-    if node != None:
-        dir = ret + "/" + node
-    if init:
-        os.system('mkdir -p ' + dir)
-        os.system('chmod -R go+rw /tmp/topotests')
-    return ret
 
 def json_diff(d1, d2):
     """
@@ -612,7 +595,21 @@ class Router(Node):
 
     def __init__(self, name, **params):
         super(Router, self).__init__(name, **params)
-        self.logdir = params.get('logdir', get_test_logdir(name, True))
+        self.logdir = params.get('logdir')
+
+        # If this topology is using old API and doesn't have logdir
+        # specified, then attempt to generate an unique logdir.
+        if self.logdir is None:
+            cur_test = os.environ['PYTEST_CURRENT_TEST']
+            self.logdir = ('/tmp/topotests/' +
+                           cur_test[0:cur_test.find(".py")].replace('/', '.'))
+
+        # If the logdir is not created, then create it and set the
+        # appropriated permissions.
+        if not os.path.isdir(self.logdir):
+            os.system('mkdir -p ' + self.logdir + '/' + name)
+            os.system('chmod -R go+rw /tmp/topotests')
+
         self.daemondir = None
         self.hasmpls = False
         self.routertype = 'frr'
index 128f397552e506b3075297b9db81bd16f73e86ca..7114a3286be1b3e36b7dca5584f1147f5b1d14d3 100644 (file)
@@ -272,7 +272,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)
                                ifp->vrf_id, ifp->name,
                                prefix2str(&p, buf, sizeof(buf)));
                }
-               mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id));
+               mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), &p);
        }
 }
 
@@ -437,7 +437,7 @@ void connected_down(struct interface *ifp, struct connected *ifc)
                                ifp->vrf_id, ifp->name,
                                prefix2str(&p, buf, sizeof(buf)));
                }
-               mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id));
+               mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), &p);
        }
 }
 
@@ -471,7 +471,7 @@ static void connected_delete_helper(struct connected *ifc, struct prefix *p)
                                ifp->vrf_id, ifp->name,
                                prefix2str(p, buf, sizeof(buf)));
                }
-               mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id));
+               mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), p);
        }
 }
 
index 87999a1bbce03e66976b66e967959e8ee7d42d11..8e5fb0ea103b8e4474a242753204b8665b6e2406 100644 (file)
@@ -87,7 +87,9 @@ DEFUN_NOSH (show_debugging_zebra,
 
        if (IS_ZEBRA_DEBUG_FPM)
                vty_out(vty, "  Zebra FPM debugging is on\n");
-       if (IS_ZEBRA_DEBUG_NHT)
+       if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+               vty_out(vty, "  Zebra detailed next-hop tracking debugging is on\n");
+       else if (IS_ZEBRA_DEBUG_NHT)
                vty_out(vty, "  Zebra next-hop tracking debugging is on\n");
        if (IS_ZEBRA_DEBUG_MPLS)
                vty_out(vty, "  Zebra MPLS debugging is on\n");
@@ -119,12 +121,19 @@ DEFUN (debug_zebra_events,
 
 DEFUN (debug_zebra_nht,
        debug_zebra_nht_cmd,
-       "debug zebra nht",
+       "debug zebra nht [detailed]",
        DEBUG_STR
        "Zebra configuration\n"
-       "Debug option set for zebra next hop tracking\n")
+       "Debug option set for zebra next hop tracking\n"
+       "Debug option set for detailed info\n")
 {
+       int idx = 0;
+
        zebra_debug_nht = ZEBRA_DEBUG_NHT;
+
+       if (argv_find(argv, argc, "detailed", &idx))
+               zebra_debug_nht |= ZEBRA_DEBUG_NHT_DETAILED;
+
        return CMD_SUCCESS;
 }
 
@@ -320,11 +329,12 @@ DEFUN (no_debug_zebra_events,
 
 DEFUN (no_debug_zebra_nht,
        no_debug_zebra_nht_cmd,
-       "no debug zebra nht",
+       "no debug zebra nht [detailed]",
        NO_STR
        DEBUG_STR
        "Zebra configuration\n"
-       "Debug option set for zebra next hop tracking\n")
+       "Debug option set for zebra next hop tracking\n"
+       "Debug option set for detailed info\n")
 {
        zebra_debug_nht = 0;
        return CMD_SUCCESS;
@@ -490,10 +500,15 @@ static int config_write_debug(struct vty *vty)
                vty_out(vty, "debug zebra fpm\n");
                write++;
        }
-       if (IS_ZEBRA_DEBUG_NHT) {
+
+       if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+               vty_out(vty, "debug zebra nht detailed\n");
+               write++;
+       } else if (IS_ZEBRA_DEBUG_NHT) {
                vty_out(vty, "debug zebra nht\n");
                write++;
        }
+
        if (IS_ZEBRA_DEBUG_MPLS) {
                vty_out(vty, "debug zebra mpls\n");
                write++;
@@ -530,6 +545,7 @@ void zebra_debug_init(void)
        zebra_debug_pw = 0;
        zebra_debug_dplane = 0;
        zebra_debug_mlag = 0;
+       zebra_debug_nht = 0;
 
        install_node(&debug_node, config_write_debug);
 
index 944ad6d68b44f4b3588b5c9d75a3424287074756..176226f7ae402b5ff0d10645ddc1a6d5b1dd8688 100644 (file)
@@ -44,7 +44,9 @@ extern "C" {
 #define ZEBRA_DEBUG_RIB_DETAILED   0x02
 
 #define ZEBRA_DEBUG_FPM     0x01
-#define ZEBRA_DEBUG_NHT     0x01
+
+#define ZEBRA_DEBUG_NHT 0x01
+#define ZEBRA_DEBUG_NHT_DETAILED 0x02
 
 #define ZEBRA_DEBUG_MPLS    0x01
 
@@ -76,7 +78,10 @@ extern "C" {
 #define IS_ZEBRA_DEBUG_RIB_DETAILED  (zebra_debug_rib & ZEBRA_DEBUG_RIB_DETAILED)
 
 #define IS_ZEBRA_DEBUG_FPM (zebra_debug_fpm & ZEBRA_DEBUG_FPM)
+
 #define IS_ZEBRA_DEBUG_NHT  (zebra_debug_nht & ZEBRA_DEBUG_NHT)
+#define IS_ZEBRA_DEBUG_NHT_DETAILED (zebra_debug_nht & ZEBRA_DEBUG_NHT_DETAILED)
+
 #define IS_ZEBRA_DEBUG_MPLS  (zebra_debug_mpls & ZEBRA_DEBUG_MPLS)
 #define IS_ZEBRA_DEBUG_VXLAN (zebra_debug_vxlan & ZEBRA_DEBUG_VXLAN)
 #define IS_ZEBRA_DEBUG_PW  (zebra_debug_pw & ZEBRA_DEBUG_PW)
index c605050c57fe37ae2e70665573bfebc0cd974c49..184e798bd070f1484804082a8df794dc14d46774 100644 (file)
@@ -153,7 +153,9 @@ static void sigint(void)
        for (ALL_LIST_ELEMENTS(zrouter.client_list, ln, nn, client))
                zserv_close_client(client);
 
+       zserv_close();
        list_delete_all_node(zrouter.client_list);
+
        zebra_ptm_finish();
 
        if (retain_mode)
index ced6692b9b1bfa5773d0dcc504abf5ca5b58daf8..e26831e1a6427b7d4e2dda7f625aff06aa735d37 100644 (file)
@@ -144,6 +144,15 @@ typedef struct rib_dest_t_ {
         */
        uint32_t flags;
 
+       /*
+        * The list of nht prefixes that have ended up
+        * depending on this route node.
+        * After route processing is returned from
+        * the data plane we will run evaluate_rnh
+        * on these prefixes.
+        */
+       struct list *nht;
+
        /*
         * Linkage to put dest on the FPM processing queue.
         */
@@ -172,6 +181,8 @@ typedef struct rib_dest_t_ {
  */
 #define RIB_DEST_UPDATE_FPM    (1 << (ZEBRA_MAX_QINDEX + 2))
 
+#define RIB_DEST_UPDATE_LSPS   (1 << (ZEBRA_MAX_QINDEX + 3))
+
 /*
  * Macro to iterate over each route for a destination (prefix).
  */
@@ -359,6 +370,8 @@ extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter);
 
 extern uint8_t route_distance(int type);
 
+extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq);
+
 /*
  * Inline functions.
  */
@@ -430,6 +443,11 @@ static inline struct zebra_vrf *rib_dest_vrf(rib_dest_t *dest)
        return rib_table_info(rib_dest_table(dest))->zvrf;
 }
 
+/*
+ * Create the rib_dest_t and attach it to the specified node
+ */
+extern rib_dest_t *zebra_rib_create_dest(struct route_node *rn);
+
 /*
  * rib_tables_iter_init
  */
index bc91edd802f2e8f0c372c5f5fb28df309a5545a6..2c77af2aad9f12a9962956f83ad4bf13f4ff1309 100644 (file)
@@ -35,6 +35,9 @@
 extern "C" {
 #endif
 
+#define RSYSTEM_ROUTE(type)                                            \
+       ((type) == ZEBRA_ROUTE_KERNEL || (type) == ZEBRA_ROUTE_CONNECT)
+
 /*
  * Update or delete a route, LSP, or pseudowire from the kernel,
  * using info from a dataplane context.
index cf61eb6cb48b2d7acd8bae2e4f20d2086fdc7d7d..289ed5a15b147acda0cfe996c384ba967cbeff29 100644 (file)
@@ -1836,7 +1836,9 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
                         * of the route delete.  If that happens yeah we're
                         * screwed.
                         */
-                       (void)netlink_route_multipath(RTM_DELROUTE, ctx);
+                       if (!RSYSTEM_ROUTE(dplane_ctx_get_old_type(ctx)))
+                               (void)netlink_route_multipath(RTM_DELROUTE,
+                                                             ctx);
                        cmd = RTM_NEWROUTE;
                }
 
@@ -1844,7 +1846,10 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
                return ZEBRA_DPLANE_REQUEST_FAILURE;
        }
 
-       ret = netlink_route_multipath(cmd, ctx);
+       if (!RSYSTEM_ROUTE(dplane_ctx_get_type(ctx)))
+               ret = netlink_route_multipath(cmd, ctx);
+       else
+               ret = 0;
        if ((cmd == RTM_NEWROUTE) && (ret == 0)) {
                /* Update installed nexthops to signal which have been
                 * installed.
index f25259f300cef721a1edf47fb91a57d07d212a93..8d8bdd0a6df839c09c31d89ff4b561ec722e1681 100644 (file)
@@ -304,33 +304,41 @@ static int kernel_rtm(int cmd, const struct prefix *p,
 enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
 {
        enum zebra_dplane_result res = ZEBRA_DPLANE_REQUEST_SUCCESS;
+       uint32_t type, old_type;
 
        if (dplane_ctx_get_src(ctx) != NULL) {
                zlog_err("route add: IPv6 sourcedest routes unsupported!");
                return ZEBRA_DPLANE_REQUEST_FAILURE;
        }
 
+       type = dplane_ctx_get_type(ctx);
+       old_type = dplane_ctx_get_old_type(ctx);
+
        frr_elevate_privs(&zserv_privs) {
 
-               if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_DELETE)
-                       kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
-                                  dplane_ctx_get_ng(ctx),
-                                  dplane_ctx_get_metric(ctx));
-               else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_INSTALL)
-                       kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
-                                  dplane_ctx_get_ng(ctx),
-                                  dplane_ctx_get_metric(ctx));
-               else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_UPDATE) {
+               if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_DELETE) {
+                       if (!RSYSTEM_ROUTE(type))
+                               kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
+                                          dplane_ctx_get_ng(ctx),
+                                          dplane_ctx_get_metric(ctx));
+               } else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_INSTALL) {
+                       if (!RSYSTEM_ROUTE(type))
+                               kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
+                                          dplane_ctx_get_ng(ctx),
+                                          dplane_ctx_get_metric(ctx));
+               } else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_UPDATE) {
                        /* Must do delete and add separately -
                         * no update available
                         */
-                       kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
-                                  dplane_ctx_get_old_ng(ctx),
-                                  dplane_ctx_get_old_metric(ctx));
-
-                       kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
-                                  dplane_ctx_get_ng(ctx),
-                                  dplane_ctx_get_metric(ctx));
+                       if (!RSYSTEM_ROUTE(old_type))
+                               kernel_rtm(RTM_DELETE, dplane_ctx_get_dest(ctx),
+                                          dplane_ctx_get_old_ng(ctx),
+                                          dplane_ctx_get_old_metric(ctx));
+
+                       if (!RSYSTEM_ROUTE(type))
+                               kernel_rtm(RTM_ADD, dplane_ctx_get_dest(ctx),
+                                          dplane_ctx_get_ng(ctx),
+                                          dplane_ctx_get_metric(ctx));
                } else {
                        zlog_err("Invalid routing socket update op %s (%u)",
                                 dplane_op2str(dplane_ctx_get_op(ctx)),
@@ -339,6 +347,20 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
                }
        } /* Elevated privs */
 
+       if (RSYSTEM_ROUTE(type)
+           && dplane_ctx_get_op(ctx) != DPLANE_OP_ROUTE_DELETE) {
+               struct nexthop *nexthop;
+
+               for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
+                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+                               continue;
+
+                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) {
+                               SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
+                       }
+               }
+       }
+
        return res;
 }
 
index 4e97c272fb77659f5d77d3e2135132724657e0f4..2eeb1f278809cb279fe9061d052f015b149cd3f8 100644 (file)
@@ -1036,6 +1036,8 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
        uint8_t flags = 0;
        uint16_t type = cmd2type[hdr->command];
        bool exist;
+       bool flag_changed = false;
+       uint8_t orig_flags;
 
        if (IS_ZEBRA_DEBUG_NHT)
                zlog_debug(
@@ -1084,6 +1086,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
                if (!rnh)
                        return;
 
+               orig_flags = rnh->flags;
                if (type == RNH_NEXTHOP_TYPE) {
                        if (flags
                            && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
@@ -1101,9 +1104,12 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
                                UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
                }
 
+               if (orig_flags != rnh->flags)
+                       flag_changed = true;
+
                zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf));
                /* Anything not AF_INET/INET6 has been filtered out above */
-               if (!exist)
+               if (!exist || flag_changed)
                        zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, type,
                                           &p);
        }
index f8c6c794a4c64b634ed3f4c6adf07c168aae14d0..3a131e1aaf1224ca637ef7573e1f4370c69ebbfd 100644 (file)
@@ -510,28 +510,41 @@ static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type)
        return "Unknown";
 }
 
-static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf)
+static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf,
+                                                struct prefix *p)
 {
+       struct route_table *table;
+       struct route_node *rn;
+       rib_dest_t *dest;
+
        if (!zvrf)
                return;
 
-       zvrf->mpls_flags |= MPLS_FLAG_SCHEDULE_LSPS;
+       table = zvrf->table[family2afi(p->family)][SAFI_UNICAST];
+       if (!table)
+               return;
+
+       rn = route_node_match(table, p);
+       if (!rn)
+               return;
+
+
+       dest = rib_dest_from_rnode(rn);
+       SET_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
 }
 
-static inline void mpls_unmark_lsps_for_processing(struct zebra_vrf *zvrf)
+static inline void mpls_unmark_lsps_for_processing(struct route_node *rn)
 {
-       if (!zvrf)
-               return;
+       rib_dest_t *dest = rib_dest_from_rnode(rn);
 
-       zvrf->mpls_flags &= ~MPLS_FLAG_SCHEDULE_LSPS;
+       UNSET_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
 }
 
-static inline int mpls_should_lsps_be_processed(struct zebra_vrf *zvrf)
+static inline int mpls_should_lsps_be_processed(struct route_node *rn)
 {
-       if (!zvrf)
-               return 0;
+       rib_dest_t *dest = rib_dest_from_rnode(rn);
 
-       return ((zvrf->mpls_flags & MPLS_FLAG_SCHEDULE_LSPS) ? 1 : 0);
+       return !!CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
 }
 
 /* Global variables. */
index 5fa51ada45ddec4393bdfa1a8b1df582fc0af630..557e6876e2ced199605eb30f0921423437bc1f40 100644 (file)
@@ -1175,10 +1175,7 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re)
                if (zebra_rib_labeled_unicast(re))
                        zebra_mpls_lsp_uninstall(info->zvrf, rn, re);
 
-               if (!RIB_SYSTEM_ROUTE(re))
-                       rib_uninstall_kernel(rn, re);
-               else
-                       UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+               rib_uninstall_kernel(rn, re);
 
                dest->selected_fib = NULL;
 
@@ -1207,6 +1204,16 @@ static int rib_can_delete_dest(rib_dest_t *dest)
                return 0;
        }
 
+       /*
+        * Unresolved rnh's are stored on the default route's list
+        *
+        * dest->rnode can also be the source prefix node in an
+        * ipv6 sourcedest table.  Fortunately the prefix of a
+        * source prefix node can never be the default prefix.
+        */
+       if (is_default_prefix(&dest->rnode->p))
+               return 0;
+
        /*
         * Don't delete the dest if we have to update the FPM about this
         * prefix.
@@ -1218,6 +1225,88 @@ static int rib_can_delete_dest(rib_dest_t *dest)
        return 1;
 }
 
+void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq)
+{
+       rib_dest_t *dest = rib_dest_from_rnode(rn);
+       struct listnode *node, *nnode;
+       struct rnh *rnh;
+
+       /*
+        * We are storing the rnh's associated withb
+        * the tracked nexthop as a list of the rn's.
+        * Unresolved rnh's are placed at the top
+        * of the tree list.( 0.0.0.0/0 for v4 and 0::0/0 for v6 )
+        * As such for each rn we need to walk up the tree
+        * and see if any rnh's need to see if they
+        * would match a more specific route
+        */
+       while (rn) {
+               if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+                       char buf[PREFIX_STRLEN];
+
+                       zlog_debug("%s: %s Being examined for Nexthop Tracking",
+                                  __PRETTY_FUNCTION__,
+                                  srcdest_rnode2str(rn, buf, sizeof(buf)));
+               }
+               if (!dest) {
+                       rn = rn->parent;
+                       if (rn)
+                               dest = rib_dest_from_rnode(rn);
+                       continue;
+               }
+               /*
+                * If we have any rnh's stored in the nht list
+                * then we know that this route node was used for
+                * nht resolution and as such we need to call the
+                * nexthop tracking evaluation code
+                */
+               for (ALL_LIST_ELEMENTS(dest->nht, node, nnode, rnh)) {
+                       struct zebra_vrf *zvrf =
+                               zebra_vrf_lookup_by_id(rnh->vrf_id);
+                       struct prefix *p = &rnh->node->p;
+
+                       if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+                               char buf1[PREFIX_STRLEN];
+                               char buf2[PREFIX_STRLEN];
+
+                               zlog_debug("%u:%s has Nexthop(%s) depending on it, evaluating %u:%u",
+                                          zvrf->vrf->vrf_id,
+                                          srcdest_rnode2str(rn, buf1,
+                                                     sizeof(buf1)),
+                                          prefix2str(p, buf2, sizeof(buf2)),
+                                          seq, rnh->seqno);
+                       }
+
+                       /*
+                        * If we have evaluated this node on this pass
+                        * already, due to following the tree up
+                        * then we know that we can move onto the next
+                        * rnh to process.
+                        *
+                        * Additionally we call zebra_evaluate_rnh
+                        * when we gc the dest.  In this case we know
+                        * that there must be no other re's where
+                        * we were originally as such we know that
+                        * that sequence number is ok to respect.
+                        */
+                       if (rnh->seqno == seq) {
+                               if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+                                       zlog_debug(
+                                               "\tNode processed and moved already");
+                               continue;
+                       }
+
+                       rnh->seqno = seq;
+                       zebra_evaluate_rnh(zvrf, family2afi(p->family), 0,
+                                          rnh->type, p);
+               }
+
+               rn = rn->parent;
+               if (rn)
+                       dest = rib_dest_from_rnode(rn);
+       }
+}
+
 /*
  * rib_gc_dest
  *
@@ -1244,7 +1333,10 @@ int rib_gc_dest(struct route_node *rn)
                rnode_debug(rn, zvrf_id(zvrf), "removing dest from table");
        }
 
+       zebra_rib_evaluate_rn_nexthops(rn, zebra_router_get_next_sequence());
+
        dest->rnode = NULL;
+       list_delete(&dest->nht);
        XFREE(MTYPE_RIB_DEST, dest);
        rn->info = NULL;
 
@@ -1258,8 +1350,6 @@ int rib_gc_dest(struct route_node *rn)
 static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
                                struct route_entry *new)
 {
-       rib_dest_t *dest = rib_dest_from_rnode(rn);
-
        hook_call(rib_update, rn, "new route selected");
 
        /* Update real nexthop. This may actually determine if nexthop is active
@@ -1281,10 +1371,7 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
        if (zebra_rib_labeled_unicast(new))
                zebra_mpls_lsp_install(zvrf, rn, new);
 
-       if (!RIB_SYSTEM_ROUTE(new))
-               rib_install_kernel(rn, new, NULL);
-       else
-               dest->selected_fib = new;
+       rib_install_kernel(rn, new, NULL);
 
        UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
 }
@@ -1292,7 +1379,6 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
 static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
                                struct route_entry *old)
 {
-       rib_dest_t *dest = rib_dest_from_rnode(rn);
        hook_call(rib_update, rn, "removing existing route");
 
        /* Uninstall from kernel. */
@@ -1308,20 +1394,7 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
        if (zebra_rib_labeled_unicast(old))
                zebra_mpls_lsp_uninstall(zvrf, rn, old);
 
-       if (!RIB_SYSTEM_ROUTE(old))
-               rib_uninstall_kernel(rn, old);
-       else {
-               UNSET_FLAG(old->status, ROUTE_ENTRY_INSTALLED);
-               /*
-                * We are setting this to NULL here
-                * because that is what we traditionally
-                * have been doing.  I am not positive
-                * that this is the right thing to do
-                * but let's leave the code alone
-                * for the RIB_SYSTEM_ROUTE case
-                */
-               dest->selected_fib = NULL;
-       }
+       rib_uninstall_kernel(rn, old);
 
        /* Update nexthop for route, reset changed flag. */
        /* Note: this code also handles the Linux case when an interface goes
@@ -1340,9 +1413,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
                                   struct route_entry *old,
                                   struct route_entry *new)
 {
-       struct nexthop *nexthop = NULL;
        int nh_active = 0;
-       rib_dest_t *dest = rib_dest_from_rnode(rn);
 
        /*
         * We have to install or update if a new route has been selected or
@@ -1384,48 +1455,15 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
                        if (zebra_rib_labeled_unicast(old))
                                zebra_mpls_lsp_uninstall(zvrf, rn, old);
 
-                       /* Non-system route should be installed. */
-                       if (!RIB_SYSTEM_ROUTE(new)) {
-                               /* If labeled-unicast route, install transit
-                                * LSP. */
-                               if (zebra_rib_labeled_unicast(new))
-                                       zebra_mpls_lsp_install(zvrf, rn, new);
+                       /*
+                        * Non-system route should be installed.
+                        * If labeled-unicast route, install transit
+                        * LSP.
+                        */
+                       if (zebra_rib_labeled_unicast(new))
+                               zebra_mpls_lsp_install(zvrf, rn, new);
 
-                               rib_install_kernel(rn, new, old);
-                       } else {
-                               UNSET_FLAG(new->status, ROUTE_ENTRY_INSTALLED);
-                               /*
-                                * We do not need to install the
-                                * selected route because it
-                                * is already isntalled by
-                                * the system( ie not us )
-                                * so just mark it as winning
-                                * we do need to ensure that
-                                * if we uninstall a route
-                                * from ourselves we don't
-                                * over write this pointer
-                                */
-                               dest->selected_fib = new;
-                       }
-                       /* If install succeeded or system route, cleanup flags
-                        * for prior route. */
-                       if (new != old) {
-                               if (RIB_SYSTEM_ROUTE(new)) {
-                                       if (!RIB_SYSTEM_ROUTE(old))
-                                               rib_uninstall_kernel(rn, old);
-                                       else
-                                               UNSET_FLAG(
-                                                       old->status,
-                                                       ROUTE_ENTRY_INSTALLED);
-                               } else {
-                                       UNSET_FLAG(old->status,
-                                                  ROUTE_ENTRY_INSTALLED);
-                                       for (nexthop = old->ng.nexthop; nexthop;
-                                            nexthop = nexthop->next)
-                                               UNSET_FLAG(nexthop->flags,
-                                                          NEXTHOP_FLAG_FIB);
-                               }
-                       }
+                       rib_install_kernel(rn, new, old);
                }
 
                /*
@@ -1455,25 +1493,18 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
                        if (zebra_rib_labeled_unicast(old))
                                zebra_mpls_lsp_uninstall(zvrf, rn, old);
 
-                       if (!RIB_SYSTEM_ROUTE(old))
-                               rib_uninstall_kernel(rn, old);
-                       else {
-                               UNSET_FLAG(old->status, ROUTE_ENTRY_INSTALLED);
-                               dest->selected_fib = NULL;
-                       }
+                       rib_uninstall_kernel(rn, old);
                }
        } else {
                /*
                 * Same route selected; check if in the FIB and if not,
-                * re-install. This
-                * is housekeeping code to deal with race conditions in kernel
-                * with linux
-                * netlink reporting interface up before IPv4 or IPv6 protocol
-                * is ready
+                * re-install. This is housekeeping code to deal with
+                * race conditions in kernel with linux netlink reporting
+                * interface up before IPv4 or IPv6 protocol is ready
                 * to add routes.
                 */
-               if (!RIB_SYSTEM_ROUTE(new)
-                   && !CHECK_FLAG(new->status, ROUTE_ENTRY_INSTALLED))
+               if (!CHECK_FLAG(new->status, ROUTE_ENTRY_INSTALLED) ||
+                   RIB_SYSTEM_ROUTE(new))
                        rib_install_kernel(rn, new, NULL);
        }
 
@@ -1725,18 +1756,9 @@ static void rib_process(struct route_node *rn)
                        UNSET_FLAG(new_selected->status, ROUTE_ENTRY_CHANGED);
                }
 
-               if (new_selected) {
+               if (new_selected)
                        SET_FLAG(new_selected->flags, ZEBRA_FLAG_SELECTED);
 
-                       /* Special case: new route is system route, so
-                        * dataplane update will not be done - ensure we
-                        * redistribute the route.
-                        */
-                       if (RIB_SYSTEM_ROUTE(new_selected))
-                               redistribute_update(p, src_p, new_selected,
-                                                   old_selected);
-               }
-
                if (old_selected) {
                        if (!new_selected)
                                redistribute_delete(p, src_p, old_selected);
@@ -1763,6 +1785,24 @@ static void rib_process(struct route_node *rn)
        rib_gc_dest(rn);
 }
 
+static void zebra_rib_evaluate_mpls(struct route_node *rn)
+{
+       rib_dest_t *dest = rib_dest_from_rnode(rn);
+       struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
+
+       if (!dest)
+               return;
+
+       if (CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS)) {
+               if (IS_ZEBRA_DEBUG_MPLS)
+                       zlog_debug(
+                               "%u: Scheduling all LSPs upon RIB completion",
+                               zvrf_id(zvrf));
+               zebra_mpls_lsp_schedule(zvrf);
+               mpls_unmark_lsps_for_processing(rn);
+       }
+}
+
 /*
  * Utility to match route with dplane context data
  */
@@ -1821,6 +1861,30 @@ done:
        return (result);
 }
 
+static void zebra_rib_fixup_system(struct route_node *rn)
+{
+       struct route_entry *re;
+
+       RNODE_FOREACH_RE(rn, re) {
+               struct nexthop *nhop;
+
+               if (!RIB_SYSTEM_ROUTE(re))
+                       continue;
+
+               if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
+                       continue;
+
+               SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+
+               for (ALL_NEXTHOPS(re->ng, nhop)) {
+                       if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE))
+                               continue;
+
+                       SET_FLAG(nhop->flags, NEXTHOP_FLAG_FIB);
+               }
+       }
+}
+
 /*
  * Route-update results processing after async dataplane update.
  */
@@ -1836,6 +1900,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
        enum dplane_op_e op;
        enum zebra_dplane_result status;
        const struct prefix *dest_pfx, *src_pfx;
+       uint32_t seq;
 
        /* Locate rn and re(s) from ctx */
 
@@ -1912,11 +1977,13 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                        break;
        }
 
+       seq = dplane_ctx_get_seq(ctx);
+
        /*
         * Check sequence number(s) to detect stale results before continuing
         */
        if (re) {
-               if (re->dplane_sequence != dplane_ctx_get_seq(ctx)) {
+               if (re->dplane_sequence != seq) {
                        if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
                                zlog_debug("%u:%s Stale dplane result for re %p",
                                           dplane_ctx_get_vrf(ctx),
@@ -1932,7 +1999,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                                           dplane_ctx_get_vrf(ctx),
                                           dest_str, old_re);
                } else
-                       UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
+                       UNSET_FLAG(old_re->status, ROUTE_ENTRY_QUEUED);
        }
 
        switch (op) {
@@ -1987,6 +2054,17 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                                                   NEXTHOP_FLAG_FIB);
                        }
 
+                       /*
+                        * System routes are weird in that they
+                        * allow multiple to be installed that match
+                        * to the same prefix, so after we get the
+                        * result we need to clean them up so that
+                        * we can actually use them.
+                        */
+                       if ((re && RIB_SYSTEM_ROUTE(re)) ||
+                           (old_re && RIB_SYSTEM_ROUTE(old_re)))
+                               zebra_rib_fixup_system(rn);
+
                        if (zvrf) {
                                zvrf->installs++;
                                /* Set flag for nexthop tracking processing */
@@ -2010,9 +2088,10 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                        zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_INSTALLED);
 
                } else {
-                       if (re)
+                       if (re) {
                                SET_FLAG(re->status, ROUTE_ENTRY_FAILED);
-                       if (old_re)
+                               UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+                       } if (old_re)
                                SET_FLAG(old_re->status, ROUTE_ENTRY_FAILED);
                        if (re)
                                zsend_route_notify_owner(re, dest_pfx,
@@ -2052,10 +2131,24 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                                  prefix2str(dest_pfx,
                                             dest_str, sizeof(dest_str)));
                }
+
+               /*
+                * System routes are weird in that they
+                * allow multiple to be installed that match
+                * to the same prefix, so after we get the
+                * result we need to clean them up so that
+                * we can actually use them.
+                */
+               if ((re && RIB_SYSTEM_ROUTE(re)) ||
+                   (old_re && RIB_SYSTEM_ROUTE(old_re)))
+                       zebra_rib_fixup_system(rn);
                break;
        default:
                break;
        }
+
+       zebra_rib_evaluate_rn_nexthops(rn, seq);
+       zebra_rib_evaluate_mpls(rn);
 done:
 
        if (rn)
@@ -2110,47 +2203,12 @@ static unsigned int process_subq(struct list *subq, uint8_t qindex)
        return 1;
 }
 
+
 /*
  * Perform next-hop tracking processing after RIB updates.
  */
 static void do_nht_processing(void)
 {
-       struct vrf *vrf;
-       struct zebra_vrf *zvrf;
-
-       /* Evaluate nexthops for those VRFs which underwent route processing.
-        * This
-        * should limit the evaluation to the necessary VRFs in most common
-        * situations.
-        */
-       RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
-               zvrf = vrf->info;
-               if (zvrf == NULL || !(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED))
-                       continue;
-
-               if (IS_ZEBRA_DEBUG_RIB_DETAILED || IS_ZEBRA_DEBUG_NHT)
-                       zlog_debug("NHT processing check for zvrf %s",
-                                  zvrf_name(zvrf));
-
-               zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED;
-               zebra_evaluate_rnh(zvrf, AFI_IP, 0, RNH_NEXTHOP_TYPE, NULL);
-               zebra_evaluate_rnh(zvrf, AFI_IP, 0, RNH_IMPORT_CHECK_TYPE,
-                                  NULL);
-               zebra_evaluate_rnh(zvrf, AFI_IP6, 0, RNH_NEXTHOP_TYPE, NULL);
-               zebra_evaluate_rnh(zvrf, AFI_IP6, 0, RNH_IMPORT_CHECK_TYPE,
-                                  NULL);
-       }
-
-       /* Schedule LSPs for processing, if needed. */
-       zvrf = vrf_info_lookup(VRF_DEFAULT);
-       if (mpls_should_lsps_be_processed(zvrf)) {
-               if (IS_ZEBRA_DEBUG_MPLS)
-                       zlog_debug(
-                               "%u: Scheduling all LSPs upon RIB completion",
-                               zvrf_id(zvrf));
-               zebra_mpls_lsp_schedule(zvrf);
-               mpls_unmark_lsps_for_processing(zvrf);
-       }
 }
 
 /* Dispatch the meta queue by picking, processing and unlocking the next RN from
@@ -2340,6 +2398,19 @@ static void rib_queue_init(void)
        return;
 }
 
+rib_dest_t *zebra_rib_create_dest(struct route_node *rn)
+{
+       rib_dest_t *dest;
+
+       dest = XCALLOC(MTYPE_RIB_DEST, sizeof(rib_dest_t));
+       dest->nht = list_new();
+       route_lock_node(rn); /* rn route table reference */
+       rn->info = dest;
+       dest->rnode = rn;
+
+       return dest;
+}
+
 /* RIB updates are processed via a queue of pointers to route_nodes.
  *
  * The queue length is bounded by the maximal size of the routing table,
@@ -2392,10 +2463,7 @@ static void rib_link(struct route_node *rn, struct route_entry *re, int process)
                if (IS_ZEBRA_DEBUG_RIB_DETAILED)
                        rnode_debug(rn, re->vrf_id, "rn %p adding dest", rn);
 
-               dest = XCALLOC(MTYPE_RIB_DEST, sizeof(rib_dest_t));
-               route_lock_node(rn); /* rn route table reference */
-               rn->info = dest;
-               dest->rnode = rn;
+               dest = zebra_rib_create_dest(rn);
        }
 
        head = dest->routes;
@@ -2654,7 +2722,7 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id)
         * revalidation
         * of the rest of the RE.
         */
-       if (dest->selected_fib && !RIB_SYSTEM_ROUTE(dest->selected_fib)) {
+       if (dest->selected_fib) {
                changed = 1;
                if (IS_ZEBRA_DEBUG_RIB) {
                        char buf[PREFIX_STRLEN];
@@ -2676,7 +2744,6 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
        struct route_table *table;
        struct route_node *rn;
        struct route_entry *same = NULL;
-       struct nexthop *nexthop;
        int ret = 0;
 
        if (!re)
@@ -2740,13 +2807,6 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
                        break;
        }
 
-       /* If this route is kernel route, set FIB flag to the route. */
-       if (RIB_SYSTEM_ROUTE(re)) {
-               SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
-               for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
-                       SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
-       }
-
        /* Link new re to node.*/
        if (IS_ZEBRA_DEBUG_RIB) {
                rnode_debug(rn, re->vrf_id,
@@ -3222,10 +3282,8 @@ void rib_close_table(struct route_table *table)
                        if (info->safi == SAFI_UNICAST)
                                hook_call(rib_update, rn, NULL);
 
-                       if (!RIB_SYSTEM_ROUTE(dest->selected_fib)) {
-                               rib_uninstall_kernel(rn, dest->selected_fib);
-                               dest->selected_fib = NULL;
-                       }
+                       rib_uninstall_kernel(rn, dest->selected_fib);
+                       dest->selected_fib = NULL;
                }
        }
 }
index f601ab7e7bc6c9cd93f5b62f2c458a04ff15d154..a1519e45cd6d7415471430a5d7ca5fdb7365d812 100644 (file)
@@ -94,6 +94,61 @@ char *rnh_str(struct rnh *rnh, char *buf, int size)
        return buf;
 }
 
+static void zebra_rnh_remove_from_routing_table(struct rnh *rnh)
+{
+       struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id);
+       struct route_table *table = zvrf->table[rnh->afi][SAFI_UNICAST];
+       struct route_node *rn;
+       rib_dest_t *dest;
+
+       if (!table)
+               return;
+
+       rn = route_node_match(table, &rnh->resolved_route);
+       if (!rn)
+               return;
+
+       if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+               char buf[PREFIX_STRLEN];
+               char buf1[PREFIX_STRLEN];
+
+               zlog_debug("%s: %u:%s removed from tracking on %s",
+                          __PRETTY_FUNCTION__, rnh->vrf_id,
+                          prefix2str(&rnh->node->p, buf, sizeof(buf)),
+                          srcdest_rnode2str(rn, buf1, sizeof(buf)));
+       }
+
+       dest = rib_dest_from_rnode(rn);
+       listnode_delete(dest->nht, rnh);
+       route_unlock_node(rn);
+}
+
+static void zebra_rnh_store_in_routing_table(struct rnh *rnh)
+{
+       struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id);
+       struct route_table *table = zvrf->table[rnh->afi][SAFI_UNICAST];
+       struct route_node *rn;
+       rib_dest_t *dest;
+
+       rn = route_node_match(table, &rnh->resolved_route);
+       if (!rn)
+               return;
+
+       if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+               char buf[PREFIX_STRLEN];
+               char buf1[PREFIX_STRLEN];
+
+               zlog_debug("%s: %u:%s added for tracking on %s",
+                          __PRETTY_FUNCTION__, rnh->vrf_id,
+                          prefix2str(&rnh->node->p, buf, sizeof(buf)),
+                          srcdest_rnode2str(rn, buf1, sizeof(buf)));
+       }
+
+       dest = rib_dest_from_rnode(rn);
+       listnode_add(dest->nht, rnh);
+       route_unlock_node(rn);
+}
+
 struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type,
                          bool *exists)
 {
@@ -101,12 +156,13 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type,
        struct route_node *rn;
        struct rnh *rnh = NULL;
        char buf[PREFIX2STR_BUFFER];
+       afi_t afi = family2afi(p->family);
 
        if (IS_ZEBRA_DEBUG_NHT) {
                prefix2str(p, buf, sizeof(buf));
                zlog_debug("%u: Add RNH %s type %d", vrfid, buf, type);
        }
-       table = get_rnh_table(vrfid, family2afi(PREFIX_FAMILY(p)), type);
+       table = get_rnh_table(vrfid, afi, type);
        if (!table) {
                prefix2str(p, buf, sizeof(buf));
                flog_warn(EC_ZEBRA_RNH_NO_TABLE,
@@ -124,13 +180,26 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type,
 
        if (!rn->info) {
                rnh = XCALLOC(MTYPE_RNH, sizeof(struct rnh));
+
+               /*
+                * The resolved route is already 0.0.0.0/0 or
+                * 0::0/0 due to the calloc right above, but
+                * we should set the family so that future
+                * comparisons can just be done
+                */
+               rnh->resolved_route.family = p->family;
                rnh->client_list = list_new();
                rnh->vrf_id = vrfid;
+               rnh->type = type;
+               rnh->seqno = 0;
+               rnh->afi = afi;
                rnh->zebra_pseudowire_list = list_new();
                route_lock_node(rn);
                rn->info = rnh;
                rnh->node = rn;
                *exists = false;
+
+               zebra_rnh_store_in_routing_table(rnh);
        } else
                *exists = true;
 
@@ -161,9 +230,30 @@ struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
 
 void zebra_free_rnh(struct rnh *rnh)
 {
+       struct zebra_vrf *zvrf;
+       struct route_table *table;
+
+       zebra_rnh_remove_from_routing_table(rnh);
        rnh->flags |= ZEBRA_NHT_DELETED;
        list_delete(&rnh->client_list);
        list_delete(&rnh->zebra_pseudowire_list);
+
+       zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id);
+       table = zvrf->table[family2afi(rnh->resolved_route.family)][SAFI_UNICAST];
+
+       if (table) {
+               struct route_node *rern;
+
+               rern = route_node_match(table, &rnh->resolved_route);
+               if (rern) {
+                       rib_dest_t *dest;
+
+                       route_unlock_node(rern);
+
+                       dest = rib_dest_from_rnode(rern);
+                       listnode_delete(dest->nht, rnh);
+               }
+       }
        free_state(rnh->vrf_id, rnh->state, rnh->node);
        XFREE(MTYPE_RNH, rnh);
 }
@@ -344,6 +434,16 @@ zebra_rnh_resolve_import_entry(struct zebra_vrf *zvrf, afi_t afi,
            && !prefix_same(&nrn->p, &rn->p))
                return NULL;
 
+       if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+               char buf[PREFIX_STRLEN];
+               char buf1[PREFIX_STRLEN];
+
+               zlog_debug("%s: %u:%s Resolved Import Entry to %s",
+                          __PRETTY_FUNCTION__, rnh->vrf_id,
+                          prefix2str(&rnh->node->p, buf, sizeof(buf)),
+                          srcdest_rnode2str(rn, buf1, sizeof(buf)));
+       }
+
        /* Identify appropriate route entry. */
        RNODE_FOREACH_RE (rn, re) {
                if (!CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)
@@ -354,6 +454,10 @@ zebra_rnh_resolve_import_entry(struct zebra_vrf *zvrf, afi_t afi,
 
        if (re)
                *prn = rn;
+
+       if (!re && IS_ZEBRA_DEBUG_NHT_DETAILED)
+               zlog_debug("\tRejected due to removed or is a bgp route");
+
        return re;
 }
 
@@ -361,9 +465,10 @@ zebra_rnh_resolve_import_entry(struct zebra_vrf *zvrf, afi_t afi,
  * See if a tracked route entry for import (by BGP) has undergone any
  * change, and if so, notify the client.
  */
-static void zebra_rnh_eval_import_check_entry(vrf_id_t vrfid, afi_t afi,
+static void zebra_rnh_eval_import_check_entry(struct zebra_vrf *zvrf, afi_t afi,
                                              int force, struct route_node *nrn,
                                              struct rnh *rnh,
+                                             struct route_node *prn,
                                              struct route_entry *re)
 {
        int state_changed = 0;
@@ -371,25 +476,40 @@ static void zebra_rnh_eval_import_check_entry(vrf_id_t vrfid, afi_t afi,
        char bufn[INET6_ADDRSTRLEN];
        struct listnode *node;
 
+       zebra_rnh_remove_from_routing_table(rnh);
+       if (prn) {
+               prefix_copy(&rnh->resolved_route, &prn->p);
+       } else {
+               int family = rnh->resolved_route.family;
+
+               memset(&rnh->resolved_route.family, 0, sizeof(struct prefix));
+               rnh->resolved_route.family = family;
+       }
+       zebra_rnh_store_in_routing_table(rnh);
+
        if (re && (rnh->state == NULL)) {
                if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
                        state_changed = 1;
        } else if (!re && (rnh->state != NULL))
                state_changed = 1;
 
-       if (compare_state(re, rnh->state))
+       if (compare_state(re, rnh->state)) {
                copy_state(rnh, re, nrn);
+               state_changed = 1;
+       }
 
        if (state_changed || force) {
                if (IS_ZEBRA_DEBUG_NHT) {
                        prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
-                       zlog_debug("%u:%s: Route import check %s %s", vrfid,
+                       zlog_debug("%u:%s: Route import check %s %s",
+                                  zvrf->vrf->vrf_id,
                                   bufn, rnh->state ? "passed" : "failed",
                                   state_changed ? "(state changed)" : "");
                }
                /* state changed, notify clients */
                for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) {
-                       send_client(rnh, client, RNH_IMPORT_CHECK_TYPE, vrfid);
+                       send_client(rnh, client,
+                                   RNH_IMPORT_CHECK_TYPE, zvrf->vrf->vrf_id);
                }
        }
 }
@@ -412,7 +532,7 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi,
        if (IS_ZEBRA_DEBUG_NHT) {
                prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
                if (prn && re) {
-                       prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN);
+                       srcdest_rnode2str(prn, bufp, INET6_ADDRSTRLEN);
                        zlog_debug("%u:%s: NH resolved over route %s",
                                   zvrf->vrf->vrf_id, bufn, bufp);
                } else
@@ -545,19 +665,43 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
         * most-specific match. Do similar logic as in zebra_rib.c
         */
        while (rn) {
+               if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
+                       char buf[PREFIX_STRLEN];
+                       char buf1[PREFIX_STRLEN];
+
+                       zlog_debug("%s: %u:%s Possible Match to %s",
+                                  __PRETTY_FUNCTION__, rnh->vrf_id,
+                                  prefix2str(&rnh->node->p, buf, sizeof(buf)),
+                                  srcdest_rnode2str(rn, buf1, sizeof(buf)));
+               }
+
                /* Do not resolve over default route unless allowed &&
                 * match route to be exact if so specified
                 */
                if (is_default_prefix(&rn->p)
-                   && !rnh_resolve_via_default(rn->p.family))
+                   && !rnh_resolve_via_default(rn->p.family)) {
+                       if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+                               zlog_debug(
+                                       "\tNot allowed to resolve through default prefix");
                        return NULL;
+               }
 
                /* Identify appropriate route entry. */
                RNODE_FOREACH_RE (rn, re) {
-                       if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
+                       if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) {
+                               if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+                                       zlog_debug(
+                                               "\tRoute Entry %s removed",
+                                               zebra_route_string(re->type));
                                continue;
-                       if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
+                       }
+                       if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
+                               if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+                                       zlog_debug(
+                                               "\tRoute Entry %s !selected",
+                                               zebra_route_string(re->type));
                                continue;
+                       }
 
                        /* Just being SELECTED isn't quite enough - must
                         * have an installed nexthop to be useful.
@@ -567,8 +711,13 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
                                        break;
                        }
 
-                       if (nexthop == NULL)
+                       if (nexthop == NULL) {
+                               if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+                                       zlog_debug(
+                                               "\tRoute Entry %s no nexthops",
+                                               zebra_route_string(re->type));
                                continue;
+                       }
 
                        if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) {
                                if ((re->type == ZEBRA_ROUTE_CONNECT)
@@ -594,10 +743,14 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
                        return re;
                }
 
-               if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
+               if (!CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
                        rn = rn->parent;
-               else
+               else {
+                       if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+                               zlog_debug(
+                                       "\tNexthop must be connected, cannot recurse up");
                        return NULL;
+               }
        }
 
        return NULL;
@@ -629,11 +782,20 @@ static void zebra_rnh_eval_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
         * the resolving route has some change (e.g., metric), there is a state
         * change.
         */
-       if (!prefix_same(&rnh->resolved_route, &prn->p)) {
+       zebra_rnh_remove_from_routing_table(rnh);
+       if (!prefix_same(&rnh->resolved_route, prn ? NULL : &prn->p)) {
                if (prn)
                        prefix_copy(&rnh->resolved_route, &prn->p);
-               else
+               else {
+                       /*
+                        * Just quickly store the family of the resolved
+                        * route so that we can reset it in a second here
+                        */
+                       int family = rnh->resolved_route.family;
+
                        memset(&rnh->resolved_route, 0, sizeof(struct prefix));
+                       rnh->resolved_route.family = family;
+               }
 
                copy_state(rnh, re, nrn);
                state_changed = 1;
@@ -641,6 +803,7 @@ static void zebra_rnh_eval_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
                copy_state(rnh, re, nrn);
                state_changed = 1;
        }
+       zebra_rnh_store_in_routing_table(rnh);
 
        if (state_changed || force) {
                /* NOTE: Use the "copy" of resolving route stored in 'rnh' i.e.,
@@ -689,8 +852,8 @@ static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi,
 
        /* Process based on type of entry. */
        if (type == RNH_IMPORT_CHECK_TYPE)
-               zebra_rnh_eval_import_check_entry(zvrf->vrf->vrf_id, afi, force,
-                                                 nrn, rnh, re);
+               zebra_rnh_eval_import_check_entry(zvrf, afi, force, nrn, rnh,
+                                                 prn, re);
        else
                zebra_rnh_eval_nexthop_entry(zvrf, afi, force, nrn, rnh, prn,
                                             re);
@@ -790,7 +953,6 @@ void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty,
 static void free_state(vrf_id_t vrf_id, struct route_entry *re,
                       struct route_node *rn)
 {
-
        if (!re)
                return;
 
index 0e71e8a68da36eec9c8b4da4062365a504f2eab2..7d823c7acc7a4dd652cd26755c7a9815043a04fd 100644 (file)
@@ -29,6 +29,8 @@
 extern "C" {
 #endif
 
+typedef enum { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE } rnh_type_t;
+
 /* Nexthop structure. */
 struct rnh {
        uint8_t flags;
@@ -40,6 +42,12 @@ struct rnh {
        /* VRF identifier. */
        vrf_id_t vrf_id;
 
+       afi_t afi;
+
+       rnh_type_t type;
+
+       uint32_t seqno;
+
        struct route_entry *state;
        struct prefix resolved_route;
        struct list *client_list;
@@ -55,8 +63,6 @@ struct rnh {
        int filtered[ZEBRA_ROUTE_MAX];
 };
 
-typedef enum { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE } rnh_type_t;
-
 extern int zebra_rnh_ip_default_route;
 extern int zebra_rnh_ipv6_default_route;
 
index cabc8be8ddbc004ee44bf6d27829e569ee3303b8..9e09cbca3fb546efa986f93e9c4b56be956dd9a0 100644 (file)
@@ -164,8 +164,6 @@ static void zebra_router_free_table(struct zebra_router_table *zrt)
 {
        void *table_info;
 
-       rib_close_table(zrt->table);
-
        table_info = route_table_get_info(zrt->table);
        route_table_finish(zrt->table);
        RB_REMOVE(zebra_router_table_head, &zrouter.tables, zrt);
index 90f94902f341c235b8a4aa8a7c8241f259e6762d..2d721ec8a1a53ca6e8a396e438b0184ace37ceb8 100644 (file)
@@ -354,7 +354,12 @@ void zebra_rtable_node_cleanup(struct route_table *table,
                rib_unlink(node, re);
        }
 
-       XFREE(MTYPE_RIB_DEST, node->info);
+       if (node->info) {
+               rib_dest_t *dest = node->info;
+
+               list_delete(&dest->nht);
+               XFREE(MTYPE_RIB_DEST, node->info);
+       }
 }
 
 static void zebra_rnhtable_node_cleanup(struct route_table *table,
@@ -370,10 +375,19 @@ static void zebra_rnhtable_node_cleanup(struct route_table *table,
 static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
                                   safi_t safi)
 {
+       struct route_node *rn;
+       struct prefix p;
+
        assert(!zvrf->table[afi][safi]);
 
        zvrf->table[afi][safi] =
                zebra_router_get_table(zvrf, zvrf->table_id, afi, safi);
+
+       memset(&p, 0, sizeof(p));
+       p.family = afi2family(afi);
+
+       rn = srcdest_rnode_get(zvrf->table[afi][safi], &p, NULL);
+       zebra_rib_create_dest(rn);
 }
 
 /* Allocate new zebra VRF. */
index 6532491cefe5821c3a774108cdb4f349bfcf1b05..f5bb3aabb767428bccadcc61c4d33745784d2c39 100644 (file)
@@ -773,6 +773,18 @@ static int zserv_accept(struct thread *thread)
        return 0;
 }
 
+void zserv_close(void)
+{
+       /*
+        * On shutdown, let's close the socket down
+        * so that long running processes of killing the
+        * routing table doesn't leave us in a bad
+        * state where a client tries to reconnect
+        */
+       close(zsock);
+       zsock = -1;
+}
+
 void zserv_start(char *path)
 {
        int ret;
index c4c3e1328b5bb04974ce4bbad46dab0feaad07b8..86863d961c2bf961f87dd727f172b65027a6ce9c 100644 (file)
@@ -183,6 +183,13 @@ extern unsigned int multipath_num;
  */
 extern void zserv_init(void);
 
+/*
+ * Stop the Zebra API server.
+ *
+ * closes the socket
+ */
+extern void zserv_close(void);
+
 /*
  * Start Zebra API server.
  *