]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #2681 from qlyoung/doc-cleanup-rpki
authorJafar Al-Gharaibeh <Jafaral@users.noreply.github.com>
Wed, 25 Jul 2018 22:04:02 +0000 (17:04 -0500)
committerGitHub <noreply@github.com>
Wed, 25 Jul 2018 22:04:02 +0000 (17:04 -0500)
doc: cleanup rpki.rst

72 files changed:
Makefile.am
bgpd/Makefile.am
bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_attr_evpn.c
bgpd/bgp_attr_evpn.h
bgpd/bgp_debug.c
bgpd/bgp_ecommunity.h
bgpd/bgp_evpn.c
bgpd/bgp_evpn_private.h
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c
bgpd/bgpd.c
configure.ac
doc/Makefile.am
doc/developer/modules.rst
doc/developer/workflow.rst
doc/extra/spelling_wordlist.txt
doc/user/index.rst
doc/user/ldpd.rst [new file with mode: 0644]
isisd/isis_circuit.c
isisd/isis_routemap.c
ldpd/ldp_vty_cmds.c
lib/compiler.h
lib/filter.c
lib/filter.h
lib/linklist.h
lib/module.c
lib/plist.c
lib/plist.h
lib/routemap.c
lib/routemap.h
lib/stream.h
lib/vrf.c
lib/workqueue.h
lib/zclient.h
ospf6d/ospf6_asbr.c
ospf6d/ospf6_top.c
ospfd/ospf_routemap.c
pimd/pim_cmd.c
pimd/pim_ifchannel.c
pimd/pim_igmp.c
pimd/pim_nht.c
pimd/pim_nht.h
pimd/pim_rp.c
pimd/pim_rpf.c
pimd/pim_zebra.c
redhat/frr.spec.in
ripd/rip_routemap.c
ripngd/ripng_routemap.c
tests/bgpd/test_bgp_table.c
tests/bgpd/test_capability.c
tests/isisd/test_isis_vertex_queue.c
tests/lib/test_srcdest_table.c
tools/frr-reload.py
zebra/if_netlink.c
zebra/main.c
zebra/rt.h
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/rule_netlink.c
zebra/zebra_netns_notify.c
zebra/zebra_ptm.c
zebra/zebra_rib.c
zebra/zebra_routemap.c
zebra/zebra_routemap.h
zebra/zebra_vty.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h
zebra/zebra_vxlan_private.h
zebra/zserv.c

index ed22c60e7c748704a0a9bd4e4a4e30a2925e41d2..f9fb231962c7e99405c4189dbe60743f67f11737 100644 (file)
@@ -5,8 +5,7 @@ include common.am
 
 AM_CPPFLAGS += -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/lib \
              -I$(top_builddir) -I$(top_builddir)/include -I$(top_builddir)/lib
-VERSION_TYPE := $(shell if echo $(VERSION) | grep -q '^[0-9\.]*$$'; then echo RELEASE ; else echo DEV ; fi)
-DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE) -DVERSION_TYPE_$(VERSION_TYPE)
+DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE)
 LIBCAP = @LIBCAP@
 
 EXTRA_DIST =
index 3880d2020da26da4ac1f29915de2dfdd613d750e..2f19bbbd739cb28f0f09fbdb71bb538a0fd51906 100644 (file)
@@ -134,6 +134,7 @@ dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2 \
 
 bgp_vty.o: bgp_vty_clippy.c
 bgp_route.o: bgp_route_clippy.c
+bgp_debug.o: bgp_debug_clippy.c
 
 EXTRA_DIST = BGP4-MIB.txt
 
index 6596e7cfa2643d1e4b650ecdeb4d5705d3762230..e5ad5e23387ab3fa2bc348f0afd9bb050292ce0c 100644 (file)
@@ -1890,6 +1890,16 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
        /* Check if this is a Gateway MAC-IP advertisement */
        attr->default_gw = bgp_attr_default_gw(attr);
 
+       /* Handle scenario where router flag ecommunity is not
+        * set but default gw ext community is present.
+        * Use default gateway, set and propogate R-bit.
+        */
+       if (attr->default_gw)
+               attr->router_flag = 1;
+
+       /* Check EVPN Neighbor advertisement flags, R-bit */
+       bgp_attr_evpn_na_flag(attr, &attr->router_flag);
+
        /* Extract the Rmac, if any */
        bgp_attr_rmac(attr, &attr->rmac);
 
index f17c2a68e4533780614a99586205adfb62667412..883b129136220645e80aa1d63947e4dbda0170c3 100644 (file)
@@ -185,6 +185,9 @@ struct attr {
        /* Flag for default gateway extended community in EVPN */
        uint8_t default_gw;
 
+       /* NA router flag (R-bit) support in EVPN */
+       uint8_t router_flag;
+
        /* route tag */
        route_tag_t tag;
 
index 14ff01ada54c09eb56466857557959c30f71d90d..88e520fdc508c24de4fdd1014124cd9cf3dee105 100644 (file)
@@ -210,6 +210,39 @@ uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, uint8_t *sticky)
        return 0;
 }
 
+/*
+ * return true if attr contains router flag extended community
+ */
+void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag)
+{
+       struct ecommunity *ecom;
+       int i;
+       uint8_t val;
+
+       ecom = attr->ecommunity;
+       if (!ecom || !ecom->size)
+               return;
+
+       /* If there is a evpn na extendd community set router_flag */
+       for (i = 0; i < ecom->size; i++) {
+               uint8_t *pnt;
+               uint8_t type, sub_type;
+
+               pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
+               type = *pnt++;
+               sub_type = *pnt++;
+
+               if (type == ECOMMUNITY_ENCODE_EVPN &&
+                   sub_type == ECOMMUNITY_EVPN_SUBTYPE_ND) {
+                       val = *pnt++;
+                       if (val & ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG) {
+                               *router_flag = 1;
+                               break;
+                       }
+               }
+       }
+}
+
 /* dst prefix must be AF_INET or AF_INET6 prefix, to forge EVPN prefix */
 extern int bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag,
                                 struct prefix *dst)
index 7454b81b966870903f72b4ce05365aebef73fa8d..b036702151d0e01957bec7d693bd765a1374dd6d 100644 (file)
@@ -65,4 +65,6 @@ extern uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr,
                                             uint8_t *sticky);
 extern uint8_t bgp_attr_default_gw(struct attr *attr);
 
+extern void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag);
+
 #endif /* _QUAGGA_BGP_ATTR_EVPN_H */
index a4ded57c25630d2008103bbcbb5a3e5a2bd62e43..1e95a887bc5bf63e928c4f8b06d3a435e343bd0b 100644 (file)
@@ -42,6 +42,8 @@
 #include "bgpd/bgp_ecommunity.h"
 #include "bgpd/bgp_label.h"
 #include "bgpd/bgp_evpn.h"
+#include "bgpd/bgp_evpn_private.h"
+#include "bgpd/bgp_vty.h"
 #include "bgpd/bgp_flowspec.h"
 
 unsigned long conf_bgp_debug_as4;
@@ -169,6 +171,8 @@ static const struct message bgp_notify_capability_msg[] = {
 const char *bgp_origin_str[] = {"i", "e", "?"};
 const char *bgp_origin_long_str[] = {"IGP", "EGP", "incomplete"};
 
+static int bgp_debug_print_evpn_prefix(struct vty *vty, const char *desc,
+                                      struct prefix *p);
 /* Given a string return a pointer the corresponding peer structure */
 static struct peer *bgp_find_peer(struct vty *vty, const char *peer_str)
 {
@@ -216,11 +220,11 @@ static void bgp_debug_list_free(struct list *list)
 /* Print the desc along with a list of peers/prefixes this debug is
  * enabled for */
 static void bgp_debug_list_print(struct vty *vty, const char *desc,
-                                struct list *list)
+                                struct list *list, uint8_t evpn_dbg)
 {
        struct bgp_debug_filter *filter;
        struct listnode *node, *nnode;
-       char buf[INET6_ADDRSTRLEN];
+       char buf[PREFIX2STR_BUFFER];
 
        vty_out(vty, "%s", desc);
 
@@ -230,12 +234,17 @@ static void bgp_debug_list_print(struct vty *vty, const char *desc,
                        if (filter->host)
                                vty_out(vty, " %s", filter->host);
 
-                       if (filter->p)
-                               vty_out(vty, " %s/%d",
-                                       inet_ntop(filter->p->family,
-                                                 &filter->p->u.prefix, buf,
-                                                 INET6_ADDRSTRLEN),
-                                       filter->p->prefixlen);
+                       if (filter->p) {
+                               if (!evpn_dbg) {
+                                       vty_out(vty, " %s",
+                                               prefix2str(filter->p, buf,
+                                                          sizeof(buf)));
+                               } else {
+                                       if (filter->p->family == AF_EVPN)
+                                               bgp_debug_print_evpn_prefix(vty,
+                                                       "", filter->p);
+                               }
+                       }
                }
        }
 
@@ -246,11 +255,11 @@ static void bgp_debug_list_print(struct vty *vty, const char *desc,
  * enabled for
  */
 static int bgp_debug_list_conf_print(struct vty *vty, const char *desc,
-                                    struct list *list)
+                                    struct list *list, uint8_t evpn_dbg)
 {
        struct bgp_debug_filter *filter;
        struct listnode *node, *nnode;
-       char buf[INET6_ADDRSTRLEN];
+       char buf[PREFIX2STR_BUFFER];
        int write = 0;
 
        if (list && !list_isempty(list)) {
@@ -262,12 +271,17 @@ static int bgp_debug_list_conf_print(struct vty *vty, const char *desc,
 
 
                        if (filter->p) {
-                               vty_out(vty, "%s %s/%d\n", desc,
-                                       inet_ntop(filter->p->family,
-                                                 &filter->p->u.prefix, buf,
-                                                 INET6_ADDRSTRLEN),
-                                       filter->p->prefixlen);
-                               write++;
+                               if (!evpn_dbg) {
+                                       vty_out(vty, "%s %s\n", desc,
+                                               prefix2str(filter->p, buf,
+                                                          sizeof(buf)));
+                                       write++;
+                               } else {
+                                       if (filter->p->family == AF_EVPN)
+                                               bgp_debug_print_evpn_prefix(vty,
+                                                       desc, filter->p);
+                                       write++;
+                               }
                        }
                }
        }
@@ -543,6 +557,118 @@ static void bgp_debug_clear_updgrp_update_dbg(struct bgp *bgp)
        update_group_walk(bgp, update_group_clear_update_dbg, NULL);
 }
 
+static int bgp_debug_print_evpn_prefix(struct vty *vty, const char *desc,
+                                      struct prefix *p)
+{
+       char evpn_desc[PREFIX2STR_BUFFER + INET_ADDRSTRLEN];
+       char buf[PREFIX2STR_BUFFER];
+       char buf2[ETHER_ADDR_STRLEN];
+
+       if (p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE) {
+               if (is_evpn_prefix_ipaddr_none((struct prefix_evpn *)p)) {
+                       sprintf(evpn_desc, "l2vpn evpn type macip mac %s",
+                                prefix_mac2str(
+                                       &p->u.prefix_evpn.macip_addr.mac,
+                                       buf2, sizeof(buf2)));
+               } else {
+                       uint8_t family = is_evpn_prefix_ipaddr_v4(
+                                               (struct prefix_evpn *)p) ?
+                                                       AF_INET : AF_INET6;
+                       sprintf(evpn_desc, "l2vpn evpn type macip mac %s ip %s",
+                                prefix_mac2str(
+                                       &p->u.prefix_evpn.macip_addr.mac,
+                                       buf2, sizeof(buf2)),
+                                inet_ntop(family,
+                                       &p->u.prefix_evpn.macip_addr.ip.ip.addr,
+                                       buf, PREFIX2STR_BUFFER));
+               }
+       } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IMET_ROUTE) {
+               sprintf(evpn_desc, "l2vpn evpn type multicast ip %s",
+                       inet_ntoa(p->u.prefix_evpn.imet_addr.ip.ipaddr_v4));
+       } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IP_PREFIX_ROUTE) {
+               uint8_t family = is_evpn_prefix_ipaddr_v4(
+                                       (struct prefix_evpn *)p) ? AF_INET
+                                                               : AF_INET6;
+               sprintf(evpn_desc, "l2vpn evpn type prefix ip %s/%d",
+                       inet_ntop(family,
+                                 &p->u.prefix_evpn.prefix_addr.ip.ip.addr, buf,
+                                 PREFIX2STR_BUFFER),
+                       p->u.prefix_evpn.prefix_addr.ip_prefix_length);
+       }
+
+       vty_out(vty, "%s %s\n", desc, evpn_desc);
+
+       return 0;
+}
+
+static int bgp_debug_parse_evpn_prefix(struct vty *vty, struct cmd_token **argv,
+                                      int argc, struct prefix **argv_pp)
+{
+       struct prefix *argv_p;
+       struct ethaddr mac;
+       struct ipaddr ip;
+       int evpn_type;
+       int type_idx = 0;
+       int mac_idx = 0;
+       int ip_idx = 0;
+
+       argv_p = *argv_pp;
+
+       if (argv_find(argv, argc, "type", &type_idx) == 0)
+               return CMD_WARNING;
+
+       if (strncmp(argv[type_idx + 1]->arg, "ma", 2) == 0)
+               evpn_type = BGP_EVPN_MAC_IP_ROUTE;
+       else if (strncmp(argv[type_idx + 1]->arg, "mu", 2) == 0)
+               evpn_type = BGP_EVPN_IMET_ROUTE;
+       else if (strncmp(argv[type_idx + 1]->arg, "pr", 2) == 0)
+               evpn_type = BGP_EVPN_IP_PREFIX_ROUTE;
+       else
+               evpn_type = 0;
+
+       if (evpn_type == BGP_EVPN_MAC_IP_ROUTE) {
+               memset(&ip, 0, sizeof(struct ipaddr));
+               /* get the ip if specified */
+               if (argv_find(argv, argc, "ip", &ip_idx)) {
+                       if (str2ipaddr(argv[ip_idx + 1]->arg, &ip) != 0) {
+                               vty_out(vty, "%% Malformed IP address\n");
+                               return CMD_WARNING;
+                       }
+               }
+               argv_find(argv, argc, "mac", &mac_idx);
+               if (!prefix_str2mac(argv[mac_idx + 1]->arg, &mac)) {
+                       vty_out(vty, "%% Malformed MAC address\n");
+                       return CMD_WARNING;
+               }
+
+               build_evpn_type2_prefix((struct prefix_evpn *)argv_p,
+                                       &mac, &ip);
+       } else if (evpn_type == BGP_EVPN_IMET_ROUTE) {
+               memset(&ip, 0, sizeof(struct ipaddr));
+               /* get the ip if specified */
+               if (argv_find(argv, argc, "ip", &ip_idx)) {
+                       if (str2ipaddr(argv[ip_idx + 1]->arg, &ip) != 0) {
+                               vty_out(vty, "%% Malformed IP address\n");
+                               return CMD_WARNING;
+                       }
+               }
+               build_evpn_type3_prefix((struct prefix_evpn *)argv_p,
+                                       ip.ipaddr_v4);
+       } else if (evpn_type == BGP_EVPN_IP_PREFIX_ROUTE) {
+               struct prefix ip_prefix;
+
+               memset(&ip_prefix, 0, sizeof(struct prefix));
+               if (argv_find(argv, argc, "ip", &ip_idx)) {
+                       (void)str2prefix(argv[ip_idx + 1]->arg, &ip_prefix);
+                       apply_mask(&ip_prefix);
+               }
+               build_type5_prefix_from_ip_prefix(
+                                       (struct prefix_evpn *)argv_p,
+                                       &ip_prefix);
+       }
+
+       return CMD_SUCCESS;
+}
 
 /* Debug option setting interface. */
 unsigned long bgp_debug_option = 0;
@@ -1266,6 +1392,148 @@ DEFUN (no_debug_bgp_update_direct_peer,
        return CMD_SUCCESS;
 }
 
+#ifndef VTYSH_EXTRACT_PL
+#include "bgpd/bgp_debug_clippy.c"
+#endif
+
+DEFPY (debug_bgp_update_prefix_afi_safi,
+       debug_bgp_update_prefix_afi_safi_cmd,
+       "debug bgp updates prefix <l2vpn>$afi <evpn>$safi type <macip mac WORD [ip WORD]|multicast ip WORD |prefix ip WORD>",
+       DEBUG_STR
+       BGP_STR
+       "BGP updates\n"
+       "Specify a prefix to debug\n"
+       "l2vpn\n"
+       "evpn\n"
+       "Specify EVPN Route type\n"
+       "MAC-IP (Type-2) route\n"
+       "MAC\n"
+       "MAC address (e.g., 00:e0:ec:20:12:62)\n"
+       "IP\n"
+       "IP address (IPv4 or IPv6)\n"
+       "Multicast (Type-3) route\n"
+       "IP\n"
+       "IP address (IPv4 or IPv6)\n"
+       "Prefix (Type-5) route\n"
+       "IP\n"
+       "Prefix route\n")
+{
+       int idx_ipv4_ipv6_prefixlen = 4;
+       struct prefix *argv_p;
+       int ret = CMD_SUCCESS;
+       afi_t afiz;
+       safi_t safiz;
+
+       argv_p = prefix_new();
+
+       afiz = bgp_vty_afi_from_str(afi);
+       safiz = safi ? bgp_vty_safi_from_str(safi) : SAFI_UNICAST;
+
+       /* check for evpn route type */
+       if (afiz == AFI_L2VPN && safiz == SAFI_EVPN) {
+               ret = bgp_debug_parse_evpn_prefix(vty, argv, argc, &argv_p);
+               if (ret != CMD_SUCCESS)
+                       return ret;
+       } else {
+               (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
+               apply_mask(argv_p);
+       }
+
+       if (!bgp_debug_update_prefixes)
+               bgp_debug_update_prefixes = list_new();
+
+       if (bgp_debug_list_has_entry(bgp_debug_update_prefixes, NULL, argv_p)) {
+               vty_out(vty,
+                       "BGP updates debugging is already enabled for %s\n",
+                       argv[idx_ipv4_ipv6_prefixlen]->arg);
+               return CMD_SUCCESS;
+       }
+
+       bgp_debug_list_add_entry(bgp_debug_update_prefixes, NULL, argv_p);
+
+       if (vty->node == CONFIG_NODE) {
+               DEBUG_ON(update, UPDATE_PREFIX);
+       } else {
+               TERM_DEBUG_ON(update, UPDATE_PREFIX);
+               vty_out(vty, "BGP updates debugging is on for %s\n",
+                       argv[idx_ipv4_ipv6_prefixlen]->arg);
+       }
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (no_debug_bgp_update_prefix_afi_safi,
+       no_debug_bgp_update_prefix_afi_safi_cmd,
+       "no debug bgp updates prefix <l2vpn>$afi <evpn>$safi type <macip mac WORD [ip WORD]|multicast ip WORD |prefix ip WORD>",
+       NO_STR
+       DEBUG_STR
+       BGP_STR
+       "BGP updates\n"
+       "Specify a prefix to debug\n"
+       "l2vpn\n"
+       "evpn\n"
+       "Specify EVPN Route type\n"
+       "MAC-IP (Type-2) route\n"
+       "MAC\n"
+       "MAC address (e.g., 00:e0:ec:20:12:62)\n"
+       "IP\n"
+       "IP address (IPv4 or IPv6)\n"
+       "Multicast (Type-3) route\n"
+       "IP\n"
+       "IP address (IPv4 or IPv6)\n"
+       "Prefix (Type-5) route\n"
+       "IP\n"
+       "Prefix route\n")
+{
+       int idx_ipv4_ipv6_prefixlen = 5;
+       struct prefix *argv_p;
+       int found_prefix = 0;
+       int ret = CMD_SUCCESS;
+       afi_t afiz;
+       safi_t safiz;
+
+       argv_p = prefix_new();
+
+       afiz = bgp_vty_afi_from_str(afi);
+       safiz = safi ? bgp_vty_safi_from_str(safi) : SAFI_UNICAST;
+
+       /* check for evpn route type */
+       if (afiz == AFI_L2VPN && safiz == SAFI_EVPN) {
+               ret = bgp_debug_parse_evpn_prefix(vty, argv, argc, &argv_p);
+               if (ret != CMD_SUCCESS)
+                       return ret;
+       } else {
+               (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
+               apply_mask(argv_p);
+       }
+
+       if (bgp_debug_update_prefixes
+           && !list_isempty(bgp_debug_update_prefixes)) {
+               found_prefix = bgp_debug_list_remove_entry(
+                       bgp_debug_update_prefixes, NULL, argv_p);
+
+               if (list_isempty(bgp_debug_update_prefixes)) {
+                       if (vty->node == CONFIG_NODE) {
+                               DEBUG_OFF(update, UPDATE_PREFIX);
+                       } else {
+                               TERM_DEBUG_OFF(update, UPDATE_PREFIX);
+                               vty_out(vty,
+                                       "BGP updates debugging (per prefix) is off\n");
+                       }
+               }
+       }
+
+       if (found_prefix)
+               vty_out(vty, "BGP updates debugging is off for %s\n",
+                       argv[idx_ipv4_ipv6_prefixlen]->arg);
+       else
+               vty_out(vty, "BGP updates debugging was not enabled for %s\n",
+                       argv[idx_ipv4_ipv6_prefixlen]->arg);
+
+       return CMD_SUCCESS;
+}
+
+
 DEFUN (debug_bgp_update_prefix,
        debug_bgp_update_prefix_cmd,
        "debug bgp updates prefix <A.B.C.D/M|X:X::X:X/M>",
@@ -1816,16 +2084,16 @@ DEFUN_NOSH (show_debugging_bgp,
 
        if (BGP_DEBUG(bestpath, BESTPATH))
                bgp_debug_list_print(vty, "  BGP bestpath debugging is on",
-                                    bgp_debug_bestpath_prefixes);
+                                    bgp_debug_bestpath_prefixes, 0);
 
        if (BGP_DEBUG(keepalive, KEEPALIVE))
                bgp_debug_list_print(vty, "  BGP keepalives debugging is on",
-                                    bgp_debug_keepalive_peers);
+                                    bgp_debug_keepalive_peers, 0);
 
        if (BGP_DEBUG(neighbor_events, NEIGHBOR_EVENTS))
                bgp_debug_list_print(vty,
                                     "  BGP neighbor-events debugging is on",
-                                    bgp_debug_neighbor_events_peers);
+                                    bgp_debug_neighbor_events_peers, 0);
 
        if (BGP_DEBUG(nht, NHT))
                vty_out(vty, "  BGP next-hop tracking debugging is on\n");
@@ -1835,21 +2103,21 @@ DEFUN_NOSH (show_debugging_bgp,
 
        if (BGP_DEBUG(update, UPDATE_PREFIX))
                bgp_debug_list_print(vty, "  BGP updates debugging is on",
-                                    bgp_debug_update_prefixes);
+                                    bgp_debug_update_prefixes, 1);
 
        if (BGP_DEBUG(update, UPDATE_IN))
                bgp_debug_list_print(vty,
                                     "  BGP updates debugging is on (inbound)",
-                                    bgp_debug_update_in_peers);
+                                    bgp_debug_update_in_peers, 0);
 
        if (BGP_DEBUG(update, UPDATE_OUT))
                bgp_debug_list_print(vty,
                                     "  BGP updates debugging is on (outbound)",
-                                    bgp_debug_update_out_peers);
+                                    bgp_debug_update_out_peers, 0);
 
        if (BGP_DEBUG(zebra, ZEBRA))
                bgp_debug_list_print(vty, "  BGP zebra debugging is on",
-                                    bgp_debug_zebra_prefixes);
+                                    bgp_debug_zebra_prefixes, 0);
 
        if (BGP_DEBUG(allow_martians, ALLOW_MARTIANS))
                vty_out(vty, "  BGP allow martian next hop debugging is on\n");
@@ -1955,18 +2223,20 @@ static int bgp_config_write_debug(struct vty *vty)
 
        if (CONF_BGP_DEBUG(bestpath, BESTPATH)) {
                write += bgp_debug_list_conf_print(vty, "debug bgp bestpath",
-                                                  bgp_debug_bestpath_prefixes);
+                                                  bgp_debug_bestpath_prefixes,
+                                                  0);
        }
 
        if (CONF_BGP_DEBUG(keepalive, KEEPALIVE)) {
                write += bgp_debug_list_conf_print(vty, "debug bgp keepalives",
-                                                  bgp_debug_keepalive_peers);
+                                                  bgp_debug_keepalive_peers,
+                                                  0);
        }
 
        if (CONF_BGP_DEBUG(neighbor_events, NEIGHBOR_EVENTS)) {
                write += bgp_debug_list_conf_print(
                        vty, "debug bgp neighbor-events",
-                       bgp_debug_neighbor_events_peers);
+                       bgp_debug_neighbor_events_peers, 0);
        }
 
        if (CONF_BGP_DEBUG(nht, NHT)) {
@@ -1982,17 +2252,20 @@ static int bgp_config_write_debug(struct vty *vty)
        if (CONF_BGP_DEBUG(update, UPDATE_PREFIX)) {
                write += bgp_debug_list_conf_print(vty,
                                                   "debug bgp updates prefix",
-                                                  bgp_debug_update_prefixes);
+                                                  bgp_debug_update_prefixes,
+                                                  1);
        }
 
        if (CONF_BGP_DEBUG(update, UPDATE_IN)) {
                write += bgp_debug_list_conf_print(vty, "debug bgp updates in",
-                                                  bgp_debug_update_in_peers);
+                                                  bgp_debug_update_in_peers,
+                                                  0);
        }
 
        if (CONF_BGP_DEBUG(update, UPDATE_OUT)) {
                write += bgp_debug_list_conf_print(vty, "debug bgp updates out",
-                                                  bgp_debug_update_out_peers);
+                                                  bgp_debug_update_out_peers,
+                                                  0);
        }
 
        if (CONF_BGP_DEBUG(zebra, ZEBRA)) {
@@ -2003,7 +2276,7 @@ static int bgp_config_write_debug(struct vty *vty)
                } else {
                        write += bgp_debug_list_conf_print(
                                vty, "debug bgp zebra prefix",
-                               bgp_debug_zebra_prefixes);
+                               bgp_debug_zebra_prefixes, 0);
                }
        }
 
@@ -2095,6 +2368,10 @@ void bgp_debug_init(void)
        install_element(CONFIG_NODE, &debug_bgp_update_prefix_cmd);
        install_element(ENABLE_NODE, &no_debug_bgp_update_prefix_cmd);
        install_element(CONFIG_NODE, &no_debug_bgp_update_prefix_cmd);
+       install_element(ENABLE_NODE, &debug_bgp_update_prefix_afi_safi_cmd);
+       install_element(CONFIG_NODE, &debug_bgp_update_prefix_afi_safi_cmd);
+       install_element(ENABLE_NODE, &no_debug_bgp_update_prefix_afi_safi_cmd);
+       install_element(CONFIG_NODE, &no_debug_bgp_update_prefix_afi_safi_cmd);
 
        /* debug bgp zebra prefix A.B.C.D/M */
        install_element(ENABLE_NODE, &debug_bgp_zebra_prefix_cmd);
index 2f59308d65fd1f0f0eedfbfa9637c61ea0e3da25..c71f371a9738e2c91171c6cc8c789b4f9acf93ad 100644 (file)
 #define ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT 0x02
 #define ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC    0x03
 #define ECOMMUNITY_EVPN_SUBTYPE_DEF_GW       0x0d
+#define ECOMMUNITY_EVPN_SUBTYPE_ND           0x08
 
 #define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY 0x01
+#define ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG         0x01
+#define ECOMMUNITY_EVPN_SUBTYPE_ND_OVERRIDE_FLAG       0x02
 
 /* Low-order octet of the Extended Communities type field for OPAQUE types */
 #define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP     0x0c
index a026df59a06f717fb0cf05e630c1439d491f62e8..73f225784cb903827577b4727a74d9a042732fe8 100644 (file)
@@ -730,10 +730,13 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
        struct ecommunity ecom_sticky;
        struct ecommunity ecom_default_gw;
        struct ecommunity ecom_rmac;
+       struct ecommunity ecom_na;
        struct ecommunity_val eval;
        struct ecommunity_val eval_sticky;
        struct ecommunity_val eval_default_gw;
        struct ecommunity_val eval_rmac;
+       struct ecommunity_val eval_na;
+
        bgp_encap_types tnl_type;
        struct listnode *node, *nnode;
        struct ecommunity *ecom;
@@ -798,6 +801,15 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
                        ecommunity_merge(attr->ecommunity, &ecom_default_gw);
        }
 
+       if (attr->router_flag) {
+               memset(&ecom_na, 0, sizeof(ecom_na));
+               encode_na_flag_extcomm(&eval_na, attr->router_flag);
+               ecom_na.size = 1;
+               ecom_na.val = (uint8_t *)eval_na.val;
+               attr->ecommunity = ecommunity_merge(attr->ecommunity,
+                                                  &ecom_na);
+       }
+
        attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
 }
 
@@ -1089,6 +1101,7 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
 {
        struct bgp_info *old_select, *new_select;
        struct bgp_info_pair old_and_new;
+       struct prefix_evpn *evp;
        afi_t afi = AFI_L2VPN;
        safi_t safi = SAFI_EVPN;
        int ret = 0;
@@ -1100,6 +1113,7 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
        old_select = old_and_new.old;
        new_select = old_and_new.new;
 
+       evp = (struct prefix_evpn *)&rn->p;
        /* If the best path hasn't changed - see if there is still something to
         * update
         * to zebra RIB.
@@ -1115,6 +1129,10 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
                                SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
                        if (old_select->attr->default_gw)
                                SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+                       if (is_evpn_prefix_ipaddr_v6(evp) &&
+                           old_select->attr->router_flag)
+                               SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
+
                        ret = evpn_zebra_install(
                                bgp, vpn, (struct prefix_evpn *)&rn->p,
                                old_select->attr->nexthop, flags);
@@ -1148,6 +1166,10 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
                        SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
                if (new_select->attr->default_gw)
                        SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+               if (is_evpn_prefix_ipaddr_v6(evp) &&
+                   new_select->attr->router_flag)
+                       SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
+
                ret = evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
                                         new_select->attr->nexthop, flags);
                /* If an old best existed and it was a "local" route, the only
@@ -1695,6 +1717,8 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
        attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
        attr.sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? 1 : 0;
        attr.default_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? 1 : 0;
+       attr.router_flag = CHECK_FLAG(flags,
+                                     ZEBRA_MACIP_TYPE_ROUTER_FLAG) ? 1 : 0;
 
        /* PMSI is only needed for type-3 routes */
        if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE)
@@ -1993,11 +2017,13 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
                                update_evpn_route_entry(bgp, vpn, afi, safi, rn,
                                                        &attr_sticky, 0, 1, &ri,
                                                        0);
-                       else if (evpn_route_is_def_gw(bgp, rn))
+                       else if (evpn_route_is_def_gw(bgp, rn)) {
+                               if (is_evpn_prefix_ipaddr_v6(evp))
+                                       attr_def_gw.router_flag = 1;
                                update_evpn_route_entry(bgp, vpn, afi, safi, rn,
                                                        &attr_def_gw, 0, 1, &ri,
                                                        0);
-                       else
+                       else
                                update_evpn_route_entry(bgp, vpn, afi, safi, rn,
                                                        &attr, 0, 1, &ri, 0);
                }
index bf6a24dea61e793a7cb16ff9b4640f3b0ad7c8d0..8d71c3123e830af11eb70ac8877101f08bf46b4b 100644 (file)
@@ -311,6 +311,16 @@ static inline void encode_mac_mobility_extcomm(int static_mac, uint32_t seq,
        eval->val[7] = seq & 0xff;
 }
 
+static inline void encode_na_flag_extcomm(struct ecommunity_val *eval,
+                                         uint8_t na_flag)
+{
+       memset(eval, 0, sizeof(*eval));
+       eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
+       eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ND;
+       if (na_flag)
+               eval->val[2] |= ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG;
+}
+
 static inline void ip_prefix_from_type5_prefix(struct prefix_evpn *evp,
                                               struct prefix *ip)
 {
@@ -328,7 +338,7 @@ static inline void ip_prefix_from_type5_prefix(struct prefix_evpn *evp,
        }
 }
 
-static inline int is_evpn_prefix_default(struct prefix *evp)
+static inline int is_evpn_prefix_default(const struct prefix *evp)
 {
        if (evp->family != AF_EVPN)
                return 0;
index 795bd15613a0c41376c2b291f5903d33f2948331..f10f7425c6a6a6a79de38e1f94db50077bb32bf9 100644 (file)
@@ -8163,7 +8163,7 @@ static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
                           afi_t afi, safi_t safi, enum bgp_show_type type);
 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
                              const char *comstr, int exact, afi_t afi,
-                             safi_t safi);
+                             safi_t safi, uint8_t use_json);
 
 
 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
@@ -9038,7 +9038,6 @@ DEFUN (show_ip_bgp,
            |prefix-list WORD\
            |filter-list WORD\
            |statistics\
-           |community <AA:NN|local-AS|no-advertise|no-export|graceful-shutdown> [exact-match]\
            |community-list <(1-500)|WORD> [exact-match]\
            |A.B.C.D/M longer-prefixes\
            |X:X::X:X/M longer-prefixes\
@@ -9058,13 +9057,6 @@ DEFUN (show_ip_bgp,
        "Display routes conforming to the filter-list\n"
        "Regular expression access list name\n"
        "BGP RIB advertisement statistics\n"
-       "Display routes matching the communities\n"
-       COMMUNITY_AANN_STR
-       "Do not send outside local AS (well-known community)\n"
-       "Do not advertise to any peer (well-known community)\n"
-       "Do not export to next AS (well-known community)\n"
-       "Graceful shutdown (well-known community)\n"
-       "Exact match of the communities\n"
        "Display routes matching the community-list\n"
        "community-list number\n"
        "community-list name\n"
@@ -9079,7 +9071,6 @@ DEFUN (show_ip_bgp,
        int exact_match = 0;
        struct bgp *bgp = NULL;
        int idx = 0;
-       int idx_community_type = 0;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
                                            &bgp);
@@ -9106,24 +9097,6 @@ DEFUN (show_ip_bgp,
                return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
                                          safi, bgp_show_type_route_map);
 
-       if (argv_find(argv, argc, "community", &idx)) {
-               /* show a specific community */
-               if (argv_find(argv, argc, "local-AS", &idx_community_type)
-                   || argv_find(argv, argc, "no-advertise",
-                                &idx_community_type)
-                   || argv_find(argv, argc, "no-export", &idx_community_type)
-                   || argv_find(argv, argc, "graceful-shutdown",
-                                &idx_community_type)
-                   || argv_find(argv, argc, "AA:NN", &idx_community_type)) {
-
-                       if (argv_find(argv, argc, "exact-match", &idx))
-                               exact_match = 1;
-                       return bgp_show_community(vty, bgp,
-                                                 argv[idx_community_type]->arg,
-                                                 exact_match, afi, safi);
-               }
-       }
-
        if (argv_find(argv, argc, "community-list", &idx)) {
                const char *clist_number_or_name = argv[++idx]->arg;
                if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
@@ -9148,7 +9121,7 @@ DEFUN (show_ip_bgp_json,
           [<\
              cidr-only\
              |dampening <flap-statistics|dampened-paths>\
-             |community \
+             |community [<AA:NN|local-AS|no-advertise|no-export|graceful-shutdown>] [exact-match]\
           >] [json]",
        SHOW_STR
        IP_STR
@@ -9161,6 +9134,12 @@ DEFUN (show_ip_bgp_json,
        "Display flap statistics of routes\n"
        "Display paths suppressed due to dampening\n"
        "Display routes matching the communities\n"
+       COMMUNITY_AANN_STR
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n"
+       "Graceful shutdown (well-known community)\n"
+       "Exact match of the communities\n"
        JSON_STR)
 {
        afi_t afi = AFI_IP6;
@@ -9168,6 +9147,8 @@ DEFUN (show_ip_bgp_json,
        enum bgp_show_type sh_type = bgp_show_type_normal;
        struct bgp *bgp = NULL;
        int idx = 0;
+       int idx_community_type = 0;
+       int exact_match = 0;
 
        bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
                                            &bgp);
@@ -9193,10 +9174,31 @@ DEFUN (show_ip_bgp_json,
        }
 
        if (argv_find(argv, argc, "community", &idx)) {
-               /* show all communities */
-               return bgp_show(vty, bgp, afi, safi,
-                               bgp_show_type_community_all, NULL, uj);
+
+               /* show a specific community */
+               if (argv_find(argv, argc, "local-AS", &idx_community_type) ||
+                       argv_find(argv, argc, "no-advertise",
+                                       &idx_community_type) ||
+                       argv_find(argv, argc, "no-export",
+                                       &idx_community_type) ||
+                       argv_find(argv, argc, "graceful-shutdown",
+                                       &idx_community_type) ||
+                       argv_find(argv, argc, "AA:NN", &idx_community_type)) {
+                       if (argv_find(argv, argc, "exact-match", &idx))
+                               exact_match = 1;
+
+                       return (bgp_show_community(vty, bgp,
+                                               argv[idx_community_type]->arg,
+                                               exact_match, afi, safi, uj));
+               } else {
+
+                       /* show all communities */
+                       return (bgp_show(vty, bgp, afi, safi,
+                                       bgp_show_type_community_all, NULL,
+                                       uj));
+               }
        }
+
        return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
 }
 
@@ -9403,7 +9405,7 @@ static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
 
 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
                              const char *comstr, int exact, afi_t afi,
-                             safi_t safi)
+                             safi_t safi, uint8_t use_json)
 {
        struct community *com;
        int ret = 0;
@@ -9417,7 +9419,7 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp,
        ret = bgp_show(vty, bgp, afi, safi,
                       (exact ? bgp_show_type_community_exact
                              : bgp_show_type_community),
-                      com, 0);
+                      com, use_json);
        community_free(com);
 
        return ret;
index f9f5142cd08260763a85793dee15788474928518..903018b2a2d35bcc234a546903b0a8ff6d422374 100644 (file)
@@ -234,7 +234,8 @@ struct bgp_match_peer_compiled {
 /* Compares the peer specified in the 'match peer' clause with the peer
     received in bgp_info->peer. If it is the same, or if the peer structure
     received is a peer_group containing it, returns RMAP_MATCH. */
-static route_map_result_t route_match_peer(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_peer(void *rule,
+                                          const struct prefix *prefix,
                                           route_map_object_t type,
                                           void *object)
 {
@@ -334,7 +335,7 @@ struct route_map_rule_cmd route_match_peer_cmd = {"peer", route_match_peer,
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t route_match_ip_address(void *rule,
-                                                struct prefix *prefix,
+                                                const struct prefix *prefix,
                                                 route_map_object_t type,
                                                 void *object)
 {
@@ -374,7 +375,7 @@ struct route_map_rule_cmd route_match_ip_address_cmd = {
 
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t route_match_ip_next_hop(void *rule,
-                                                 struct prefix *prefix,
+                                                 const struct prefix *prefix,
                                                  route_map_object_t type,
                                                  void *object)
 {
@@ -421,7 +422,7 @@ struct route_map_rule_cmd route_match_ip_next_hop_cmd = {
 
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t route_match_ip_route_source(void *rule,
-                                                     struct prefix *prefix,
+                                                     const struct prefix *pfx,
                                                      route_map_object_t type,
                                                      void *object)
 {
@@ -430,7 +431,7 @@ static route_map_result_t route_match_ip_route_source(void *rule,
        struct peer *peer;
        struct prefix_ipv4 p;
 
-       if (type == RMAP_BGP && prefix->family == AF_INET) {
+       if (type == RMAP_BGP && pfx->family == AF_INET) {
                bgp_info = object;
                peer = bgp_info->peer;
 
@@ -473,7 +474,7 @@ struct route_map_rule_cmd route_match_ip_route_source_cmd = {
 /* `match ip address prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
                                   route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -508,7 +509,7 @@ struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
 /* `match ip next-hop prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
                                    route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -550,7 +551,8 @@ struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = {
 /* `match ip route-source prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ip_route_source_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_route_source_prefix_list(void *rule,
+                                       const struct prefix *prefix,
                                        route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -599,7 +601,7 @@ struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd = {
 
 /* Match function should return 1 if match is success else 0 */
 static route_map_result_t route_match_evpn_default_route(void *rule,
-                                                        struct prefix *p,
+                                                        const struct prefix *p,
                                                         route_map_object_t
                                                         type, void *object)
 {
@@ -618,7 +620,7 @@ struct route_map_rule_cmd route_match_evpn_default_route_cmd = {
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t route_match_mac_address(void *rule,
-                                                 struct prefix *prefix,
+                                                 const struct prefix *prefix,
                                                  route_map_object_t type,
                                                  void *object)
 {
@@ -667,7 +669,8 @@ struct route_map_rule_cmd route_match_mac_address_cmd = {
 
 /* Match function should return 1 if match is success else return
    zero. */
-static route_map_result_t route_match_vni(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_vni(void *rule,
+                                         const struct prefix *prefix,
                                          route_map_object_t type, void *object)
 {
        vni_t vni = 0;
@@ -722,7 +725,7 @@ struct route_map_rule_cmd route_match_evpn_vni_cmd = {
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t route_match_evpn_route_type(void *rule,
-                                                     struct prefix *prefix,
+                                                     const struct prefix *pfx,
                                                      route_map_object_t type,
                                                      void *object)
 {
@@ -731,7 +734,7 @@ static route_map_result_t route_match_evpn_route_type(void *rule,
        if (type == RMAP_BGP) {
                route_type = *((uint8_t *)rule);
 
-               if (route_type == prefix->u.prefix_evpn.route_type)
+               if (route_type == pfx->u.prefix_evpn.route_type)
                        return RMAP_MATCH;
        }
 
@@ -770,7 +773,7 @@ struct route_map_rule_cmd route_match_evpn_route_type_cmd = {
 
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t route_match_local_pref(void *rule,
-                                                struct prefix *prefix,
+                                                const struct prefix *prefix,
                                                 route_map_object_t type,
                                                 void *object)
 {
@@ -829,7 +832,8 @@ struct route_map_rule_cmd route_match_local_pref_cmd = {
 /* `match metric METRIC' */
 
 /* Match function return 1 if match is success else return zero. */
-static route_map_result_t route_match_metric(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_metric(void *rule,
+                                            const struct prefix *prefix,
                                             route_map_object_t type,
                                             void *object)
 {
@@ -852,7 +856,8 @@ struct route_map_rule_cmd route_match_metric_cmd = {
 /* `match as-path ASPATH' */
 
 /* Match function for as-path match.  I assume given object is */
-static route_map_result_t route_match_aspath(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_aspath(void *rule,
+                                            const struct prefix *prefix,
                                             route_map_object_t type,
                                             void *object)
 {
@@ -901,7 +906,7 @@ struct rmap_community {
 
 /* Match function for community match. */
 static route_map_result_t route_match_community(void *rule,
-                                               struct prefix *prefix,
+                                               const struct prefix *prefix,
                                                route_map_object_t type,
                                                void *object)
 {
@@ -969,7 +974,7 @@ struct route_map_rule_cmd route_match_community_cmd = {
 
 /* Match function for lcommunity match. */
 static route_map_result_t route_match_lcommunity(void *rule,
-                                                struct prefix *prefix,
+                                                const struct prefix *prefix,
                                                 route_map_object_t type,
                                                 void *object)
 {
@@ -1030,7 +1035,7 @@ struct route_map_rule_cmd route_match_lcommunity_cmd = {
 
 /* Match function for extcommunity match. */
 static route_map_result_t route_match_ecommunity(void *rule,
-                                                struct prefix *prefix,
+                                                const struct prefix *prefix,
                                                 route_map_object_t type,
                                                 void *object)
 {
@@ -1072,7 +1077,8 @@ struct route_map_rule_cmd route_match_ecommunity_cmd = {
    and `address-family vpnv4'.  */
 
 /* `match origin' */
-static route_map_result_t route_match_origin(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_origin(void *rule,
+                                            const struct prefix *prefix,
                                             route_map_object_t type,
                                             void *object)
 {
@@ -1120,7 +1126,7 @@ struct route_map_rule_cmd route_match_origin_cmd = {
 /* match probability  { */
 
 static route_map_result_t route_match_probability(void *rule,
-                                                 struct prefix *prefix,
+                                                 const struct prefix *prefix,
                                                  route_map_object_t type,
                                                  void *object)
 {
@@ -1175,7 +1181,7 @@ struct route_map_rule_cmd route_match_probability_cmd = {
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t route_match_interface(void *rule,
-                                               struct prefix *prefix,
+                                               const struct prefix *prefix,
                                                route_map_object_t type,
                                                void *object)
 {
@@ -1221,7 +1227,8 @@ struct route_map_rule_cmd route_match_interface_cmd = {
 /* `set ip next-hop IP_ADDRESS' */
 
 /* Match function return 1 if match is success else return zero. */
-static route_map_result_t route_match_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_tag(void *rule,
+                                         const struct prefix *prefix,
                                          route_map_object_t type, void *object)
 {
        route_tag_t *tag;
@@ -1254,7 +1261,7 @@ struct rmap_ip_nexthop_set {
 };
 
 static route_map_result_t route_set_ip_nexthop(void *rule,
-                                              struct prefix *prefix,
+                                              const struct prefix *prefix,
                                               route_map_object_t type,
                                               void *object)
 {
@@ -1362,7 +1369,7 @@ struct route_map_rule_cmd route_set_ip_nexthop_cmd = {
 
 /* Set local preference. */
 static route_map_result_t route_set_local_pref(void *rule,
-                                              struct prefix *prefix,
+                                              const struct prefix *prefix,
                                               route_map_object_t type,
                                               void *object)
 {
@@ -1396,7 +1403,8 @@ struct route_map_rule_cmd route_set_local_pref_cmd = {
 /* `set weight WEIGHT' */
 
 /* Set weight. */
-static route_map_result_t route_set_weight(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_weight(void *rule,
+                                          const struct prefix *prefix,
                                           route_map_object_t type,
                                           void *object)
 {
@@ -1424,7 +1432,8 @@ struct route_map_rule_cmd route_set_weight_cmd = {
 /* `set metric METRIC' */
 
 /* Set metric to attribute. */
-static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_metric(void *rule,
+                                          const struct prefix *prefix,
                                           route_map_object_t type,
                                           void *object)
 {
@@ -1457,7 +1466,7 @@ struct route_map_rule_cmd route_set_metric_cmd = {
 
 /* For AS path prepend mechanism. */
 static route_map_result_t route_set_aspath_prepend(void *rule,
-                                                  struct prefix *prefix,
+                                                  const struct prefix *prefix,
                                                   route_map_object_t type,
                                                   void *object)
 {
@@ -1520,7 +1529,7 @@ struct route_map_rule_cmd route_set_aspath_prepend_cmd = {
  * Make a deep copy of existing AS_PATH, but for the first ASn only.
  */
 static route_map_result_t route_set_aspath_exclude(void *rule,
-                                                  struct prefix *dummy,
+                                                  const struct prefix *dummy,
                                                   route_map_object_t type,
                                                   void *object)
 {
@@ -1554,7 +1563,8 @@ struct rmap_com_set {
 };
 
 /* For community set mechanism. */
-static route_map_result_t route_set_community(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_community(void *rule,
+                                             const struct prefix *prefix,
                                              route_map_object_t type,
                                              void *object)
 {
@@ -1670,7 +1680,7 @@ struct rmap_lcom_set {
 
 /* For lcommunity set mechanism. */
 static route_map_result_t route_set_lcommunity(void *rule,
-                                              struct prefix *prefix,
+                                              const struct prefix *prefix,
                                               route_map_object_t type,
                                               void *object)
 {
@@ -1783,7 +1793,7 @@ struct route_map_rule_cmd route_set_lcommunity_cmd = {
 
 /* For large community set mechanism. */
 static route_map_result_t route_set_lcommunity_delete(void *rule,
-                                                     struct prefix *prefix,
+                                                     const struct prefix *pfx,
                                                      route_map_object_t type,
                                                      void *object)
 {
@@ -1866,10 +1876,11 @@ struct route_map_rule_cmd route_set_lcommunity_delete_cmd = {
 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
 
 /* For community set mechanism. */
-static route_map_result_t route_set_community_delete(void *rule,
-                                                    struct prefix *prefix,
-                                                    route_map_object_t type,
-                                                    void *object)
+static route_map_result_t route_set_community_delete(
+       void *rule,
+       const struct prefix *prefix,
+       route_map_object_t type,
+       void *object)
 {
        struct community_list *list;
        struct community *merge;
@@ -1950,7 +1961,7 @@ struct route_map_rule_cmd route_set_community_delete_cmd = {
 
 /* For community set mechanism.  Used by _rt and _soo. */
 static route_map_result_t route_set_ecommunity(void *rule,
-                                              struct prefix *prefix,
+                                              const struct prefix *prefix,
                                               route_map_object_t type,
                                               void *object)
 {
@@ -2037,7 +2048,8 @@ struct route_map_rule_cmd route_set_ecommunity_soo_cmd = {
 /* `set origin ORIGIN' */
 
 /* For origin set. */
-static route_map_result_t route_set_origin(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_origin(void *rule,
+                                          const struct prefix *prefix,
                                           route_map_object_t type,
                                           void *object)
 {
@@ -2087,7 +2099,7 @@ struct route_map_rule_cmd route_set_origin_cmd = {
 
 /* For atomic aggregate set. */
 static route_map_result_t route_set_atomic_aggregate(void *rule,
-                                                    struct prefix *prefix,
+                                                    const struct prefix *pfx,
                                                     route_map_object_t type,
                                                     void *object)
 {
@@ -2127,7 +2139,7 @@ struct aggregator {
 };
 
 static route_map_result_t route_set_aggregator_as(void *rule,
-                                                 struct prefix *prefix,
+                                                 const struct prefix *prefix,
                                                  route_map_object_t type,
                                                  void *object)
 {
@@ -2180,7 +2192,8 @@ struct route_map_rule_cmd route_set_aggregator_as_cmd = {
 };
 
 /* Set tag to object. object must be pointer to struct bgp_info */
-static route_map_result_t route_set_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_tag(void *rule,
+                                       const struct prefix *prefix,
                                        route_map_object_t type, void *object)
 {
        route_tag_t *tag;
@@ -2205,7 +2218,7 @@ static struct route_map_rule_cmd route_set_tag_cmd = {
 
 /* Set label-index to object. object must be pointer to struct bgp_info */
 static route_map_result_t route_set_label_index(void *rule,
-                                               struct prefix *prefix,
+                                               const struct prefix *prefix,
                                                route_map_object_t type,
                                                void *object)
 {
@@ -2239,7 +2252,7 @@ static struct route_map_rule_cmd route_set_label_index_cmd = {
 /* `match ipv6 address IP_ACCESS_LIST' */
 
 static route_map_result_t route_match_ipv6_address(void *rule,
-                                                  struct prefix *prefix,
+                                                  const struct prefix *prefix,
                                                   route_map_object_t type,
                                                   void *object)
 {
@@ -2275,7 +2288,7 @@ struct route_map_rule_cmd route_match_ipv6_address_cmd = {
 /* `match ipv6 next-hop IP_ADDRESS' */
 
 static route_map_result_t route_match_ipv6_next_hop(void *rule,
-                                                   struct prefix *prefix,
+                                                   const struct prefix *prefix,
                                                    route_map_object_t type,
                                                    void *object)
 {
@@ -2327,7 +2340,7 @@ struct route_map_rule_cmd route_match_ipv6_next_hop_cmd = {
 /* `match ipv6 address prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ipv6_address_prefix_list(void *rule, struct prefix *prefix,
+route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
                                     route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -2363,7 +2376,7 @@ struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = {
 
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 static route_map_result_t route_set_ipv6_nexthop_global(void *rule,
-                                                       struct prefix *prefix,
+                                                       const struct prefix *p,
                                                        route_map_object_t type,
                                                        void *object)
 {
@@ -2423,7 +2436,7 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd = {
 
 /* Set next-hop preference value. */
 static route_map_result_t
-route_set_ipv6_nexthop_prefer_global(void *rule, struct prefix *prefix,
+route_set_ipv6_nexthop_prefer_global(void *rule, const struct prefix *prefix,
                                     route_map_object_t type, void *object)
 {
        struct bgp_info *bgp_info;
@@ -2477,7 +2490,7 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd = {
 
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 static route_map_result_t route_set_ipv6_nexthop_local(void *rule,
-                                                      struct prefix *prefix,
+                                                      const struct prefix *p,
                                                       route_map_object_t type,
                                                       void *object)
 {
@@ -2540,7 +2553,7 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd = {
 
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 static route_map_result_t route_set_ipv6_nexthop_peer(void *rule,
-                                                     struct prefix *prefix,
+                                                     const struct prefix *pfx,
                                                      route_map_object_t type,
                                                      void *object)
 {
@@ -2619,7 +2632,7 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd = {
 /* `set ipv4 vpn next-hop A.B.C.D' */
 
 static route_map_result_t route_set_vpnv4_nexthop(void *rule,
-                                                 struct prefix *prefix,
+                                                 const struct prefix *prefix,
                                                  route_map_object_t type,
                                                  void *object)
 {
@@ -2659,7 +2672,7 @@ static void *route_set_vpnv4_nexthop_compile(const char *arg)
 /* `set ipv6 vpn next-hop A.B.C.D' */
 
 static route_map_result_t route_set_vpnv6_nexthop(void *rule,
-                                                 struct prefix *prefix,
+                                                 const struct prefix *prefix,
                                                  route_map_object_t type,
                                                  void *object)
 {
@@ -2715,7 +2728,7 @@ struct route_map_rule_cmd route_set_vpnv6_nexthop_cmd = {
 
 /* For origin set. */
 static route_map_result_t route_set_originator_id(void *rule,
-                                                 struct prefix *prefix,
+                                                 const struct prefix *prefix,
                                                  route_map_object_t type,
                                                  void *object)
 {
index e9d9a846af810490248a7494ac75ec2a48400b74..33f5180bd365805ee1e02c018e798b60dd50f875 100644 (file)
@@ -184,6 +184,7 @@ safi_t bgp_node_safi(struct vty *vty)
  * @param afi string, one of
  *  - "ipv4"
  *  - "ipv6"
+ *  - "l2vpn"
  * @return the corresponding afi_t
  */
 afi_t bgp_vty_afi_from_str(const char *afi_str)
@@ -193,6 +194,8 @@ afi_t bgp_vty_afi_from_str(const char *afi_str)
                afi = AFI_IP;
        else if (strmatch(afi_str, "ipv6"))
                afi = AFI_IP6;
+       else if (strmatch(afi_str, "l2vpn"))
+               afi = AFI_L2VPN;
        return afi;
 }
 
@@ -222,6 +225,8 @@ safi_t bgp_vty_safi_from_str(const char *safi_str)
                safi = SAFI_UNICAST;
        else if (strmatch(safi_str, "vpn"))
                safi = SAFI_MPLS_VPN;
+       else if (strmatch(safi_str, "evpn"))
+               safi = SAFI_EVPN;
        else if (strmatch(safi_str, "labeled-unicast"))
                safi = SAFI_LABELED_UNICAST;
        else if (strmatch(safi_str, "flowspec"))
@@ -772,7 +777,7 @@ static void bgp_clear_star_soft_out(struct vty *vty, const char *name)
 #endif
 
 /* BGP global configuration.  */
-#if defined(VERSION_TYPE_DEV) && (CONFDATE > 20190601)
+#if (CONFDATE > 20190601)
 CPP_NOTICE("bgpd: time to remove deprecated bgp multiple-instance")
 CPP_NOTICE("This includes BGP_OPT_MULTIPLE_INSTANCE")
 #endif
@@ -806,7 +811,7 @@ DEFUN_HIDDEN (no_bgp_multiple_instance,
        return CMD_SUCCESS;
 }
 
-#if defined(VERSION_TYPE_DEV) && (CONFDATE > 20190601)
+#if (CONFDATE > 20190601)
 CPP_NOTICE("bgpd: time to remove deprecated cli bgp config-type cisco")
 CPP_NOTICE("This includes BGP_OPT_CISCO_CONFIG")
 #endif
@@ -2013,7 +2018,7 @@ DEFUN (no_bgp_fast_external_failover,
 }
 
 /* "bgp enforce-first-as" configuration. */
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180517
+#if CONFDATE > 20180517
 CPP_NOTICE("bgpd: remove deprecated '[no] bgp enforce-first-as' commands")
 #endif
 
@@ -9115,6 +9120,10 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, uint8_t use_json,
                json_object_string_add(
                        json_neigh, "remoteRouterId",
                        inet_ntop(AF_INET, &p->remote_id, buf1, sizeof(buf1)));
+               json_object_string_add(
+                       json_neigh, "localRouterId",
+                       inet_ntop(AF_INET, &bgp->router_id, buf1,
+                                       sizeof(buf1)));
 
                /* Confederation */
                if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
@@ -9134,7 +9143,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, uint8_t use_json,
                        uptime -= p->uptime;
                        epoch_tbuf = time(NULL) - uptime;
 
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20200101
+#if CONFDATE > 20200101
                        CPP_NOTICE(
                                "bgpTimerUp should be deprecated and can be removed now");
 #endif
index e5b269eb70c27e1f5968aaff4b88df558f8b0129..b5fb653bae1294512e628726b2b8b45ee2d848f3 100644 (file)
@@ -7356,7 +7356,7 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
 }
 
 /* clang-format off */
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180517
+#if CONFDATE > 20180517
 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
 #endif
 /* clang-format on */
index 8846fcdf717c3d031e5ca2c4c826f6529faee1a5..69a55d01eccc5d1455a53967721660efec2fbb89 100755 (executable)
@@ -1832,7 +1832,13 @@ AM_CONDITIONAL([ZEROMQ], test "x$ZEROMQ" = "xtrue")
 dnl ----------
 dnl configure date
 dnl ----------
-CONFDATE=`date '+%Y%m%d'`
+dev_version=`echo $VERSION | grep dev`
+#don't expire deprecated code in non 'dev' branch
+if test "${dev_version}" = ""; then
+   CONFDATE=0
+else
+   CONFDATE=`date '+%Y%m%d'`
+fi
 AC_SUBST(CONFDATE)
 
 dnl ------------------------------
index 62cb3c2edb452e7e859fe6eafef2d863c7ca4a08..19aab63ea3609a8db574cc3b43c00414d089ae6f 100644 (file)
@@ -193,6 +193,7 @@ EXTRA_DIST = frr-sphinx.mk \
        developer/workflow.rst \
        developer/zebra.rst \
        user/babeld.rst \
+       user/ldpd.rst \
        user/basic.rst \
        user/bgp.rst \
        user/bugs.rst \
index b832413a6cc1e6521e989123ba67d0f6231a1ed5..bde7682e4e30bd740c602a60cd69bdfcaa8f84d0 100644 (file)
@@ -100,6 +100,15 @@ a function that removes all of a module's installed hooks.
 There's also the ``frr_module`` symbol in modules, pretty much a
 standard entry point for loadable modules.
 
+Command line parameters
+-----------------------
+
+Command line parameters can be passed directly to a module by appending a 
+colon to the module name when loading it, e.g. ``-M mymodule:myparameter``. 
+The text after the colon will be accessible in the module's code through 
+``THIS_MODULE->load_args``. For example, see how the format parameter is
+configured in the ``zfpm_init()`` function inside ``zebra_fpm.c``.
+
 Hooks
 -----
 
index cd03d2733d251abc6ed0e1b2f02498cb3e37d4fa..358cb9ac7bf79434e8fe09e147ba954e2755d990 100644 (file)
@@ -776,7 +776,7 @@ annotations must be ignored non-development branches. For example:
 
 .. code-block:: c
 
-   #if defined(VERSION_TYPE_DEV) && CONFDATE > 20180403
+   #if CONFDATE > 20180403
    CPP_NOTICE("Use of <XYZ> is deprecated, please use <ABC>")
    #endif
 
index 4c9455e8e94409ede31b05856d6b7aaf90856de5..29445929625e68655d9685ec511e9591b390ba18 100644 (file)
@@ -83,6 +83,7 @@ IPv
 isis
 isisd
 lan
+ldpd
 le
 libc
 libcap
index a8109fe47970ebfbeff949f9307e08ae893cfbcb..746cc1c32dddafdfa01ce7898d3af69b01b135b4 100644 (file)
@@ -41,6 +41,7 @@ Protocols
    zebra
    bgp
    babeld
+   ldpd
    eigrpd
    isisd
    nhrpd
diff --git a/doc/user/ldpd.rst b/doc/user/ldpd.rst
new file mode 100644 (file)
index 0000000..8d88ef1
--- /dev/null
@@ -0,0 +1,309 @@
+.. _ldp:
+
+***
+LDP
+***
+
+The *ldpd* daemon is a standardised protocol that permits exchanging MPLS label
+information between MPLS devices. The LDP protocol creates peering between
+devices, so as to exchange that label information. This information is stored in
+MPLS table of *zebra*, and it injects that MPLS information in the underlying
+system (Linux kernel or OpenBSD system for instance).
+*ldpd* provides necessary options to create a Layer 2 VPN across MPLS network.
+For instance, it is possible to interconnect several sites that share the same
+broadcast domain.
+
+FRR implements LDP as described in :rfc:`5036`; other LDP standard are the
+following ones: :rfc:`6720`, :rfc:`6667`, :rfc:`5919`, :rfc:`5561`, :rfc:`7552`,
+:rfc:`4447`.
+Because MPLS is already available, FRR also supports :rfc:`3031`.
+
+Running Ldpd
+============
+
+The *ldpd* daemon can be invoked with any of the common
+options (:ref:`common-invocation-options`).
+
+The *zebra* daemon must be running before *ldpd* is invoked.
+
+Configuration of *ldpd* is done in its configuration file
+:file:`ldpd.conf`.
+
+
+.. _understanding-ldp:
+
+Understanding LDP principles
+============================
+
+Let's first introduce some definitions that permit understand better the LDP
+protocol:
+
+- `LSR` : Labeled Switch Router. Networking devices handling labels used to
+  forward traffic between and through them.
+
+- `LER` : Labeled Edge Router. A Labeled edge router is located at the edge of
+   an MPLS network, generally between an IP network and an MPLS network.
+
+
+``LDP`` aims at sharing label information across devices. It tries to establish
+peering with remote LDP capable devices, first by discovering using UDP port 646
+, then by peering using TCP port 646. Once the TCP session is established, the
+label information is shared, through label advertisements.
+
+There are different methods to send label advertisement modes. The
+implementation actually supports the following : Liberal Label Retention +
+Downstream Unsolicited + Independent Control.
+The other advertising modes are depicted below, and compared with the current
+implementation.
+
+- Liberal label retention versus conservative mode
+  In liberal mode, every label sent by every LSR is stored in the MPLS table.
+  In conservative mode, only the label that was sent by the best next hop
+  (determined by the IGP metric) for that particular FEC is stored in the MPLS
+  table.
+
+- Independent LSP Control versus ordered LSP Control
+  MPLS has two ways of binding labels to FEC’s; either through ordered LSP
+  control, or independent LSP control.
+  Ordered LSP control only binds a label to a FEC if it is the egress LSR, or
+  the router received a label binding for a FEC from the next hop router. In
+  this mode, an MPLS router will create a label binding for each FEC and
+  distribute it to its neighbors so long as he has a entry in the RIB for the
+  destination.
+  In the other mode, label bindings are made without any dependencies on another
+  router advertising a label for a particular FEC. Each router makes it own
+  independent decision to create a label for each FEC.
+  By default IOS uses Independent LSP Control, while Juniper implements the
+  Ordered Control. Both modes are interoperable, the difference is that Ordered
+  Control prevent blackholing during the LDP convergence process, at cost of
+  slowing down the convergence itself
+
+- unsolicited downstream versus downstream on demand
+  Downstream on demand label distribution is where an LSR must explicitly
+  request that a label be sent from its downstream router for a particular FEC.
+  Unsolicited label distribution is where a label is sent from the downstream
+  router without the original router requesting it.
+
+.. _configuring-ldpd:
+
+.. _ldp-configuration:
+
+LDP Configuration
+===================
+
+.. index:: [no] mpls ldp
+.. clicmd:: [no] mpls ldp
+
+   Enable or disable LDP daemon
+
+.. index:: [no] router-id A.B.C.D
+.. clicmd:: [no] router-id A.B.C.D
+
+   The following command located under MPLS router node configures the MPLS
+   router-id of the local device.
+
+.. index:: [no] address-family [ipv4 | ipv6]
+.. clicmd:: [no] address-family [ipv4 | ipv6]
+
+   Configure LDP for IPv4 or IPv6 address-family. Located under MPLS route node,
+   this subnode permits configuring the LDP neighbors.
+
+.. index:: [no] interface IFACE
+.. clicmd:: [no] interface IFACE
+
+   Located under MPLS address-family node, use this command to enable or disable
+   LDP discovery per interface. IFACE stands for the interface name where LDP is
+   enabled. By default it is disabled. Once this command executed, the
+   address-family interface node is configured.
+
+.. index:: [no] discovery transport-address A.B.C.D | A:B::C:D
+.. clicmd:: [no] discovery transport-address A.B.C.D | A:B::C:D
+
+   Located under mpls address-family interface node, use this command to set
+   the IPv4 or IPv6 transport-address used by the LDP protocol to talk on this
+   interface.
+
+.. index:: [no] neighbor A.B.C.D password PASSWORD
+.. clicmd:: [no] neighbor A.B.C.D password PASSWORD
+
+   The following command located under MPLS router node configures the router
+   of a LDP device. This device, if found, will have to comply with the
+   configured password. PASSWORD is a clear text password wit its digest sent
+   through the network.
+
+.. index:: [no] neighbor A.B.C.D holdtime HOLDTIME
+.. clicmd:: [no] neighbor A.B.C.D holdtime HOLDTIME
+
+   The following command located under MPLS router node configures the holdtime
+   value in seconds of the LDP neighbor ID. Configuring it triggers a keepalive
+   mechanism. That value can be configured between 15 and 65535 seconds. After
+   this time of non response, the LDP established session will be considered as
+   set to down. By default, no holdtime is configured for the LDP devices.
+
+.. index:: [no] discovery hello holdtime HOLDTIME
+.. clicmd:: [no] discovery hello holdtime HOLDTIME
+
+.. index:: [no] discovery hello interval INTERVAL
+.. clicmd:: [no] discovery hello interval INTERVAL
+
+   INTERVAL value ranges from 1 to 65535 seconds. Default value is 5 seconds.
+   This is the value between each hello timer message sent.
+   HOLDTIME value ranges from 1 to 65535 seconds. Default value is 15 seconds.
+   That value is added as a TLV in the LDP messages.
+
+.. _show-ldp-information:
+
+Show LDP Information
+====================
+
+These commands dump various parts of *ldpd*.
+
+.. index:: show mpls ldp neighbor [A.B.C.D]
+.. clicmd:: show mpls ldp neighbor [A.B.C.D]
+
+   This command dumps the various neighbors discovered. Below example shows that
+   local machine has an operation neighbor with ID set to 1.1.1.1.
+
+   ::
+
+      west-vm# show mpls ldp neighbor
+      AF   ID              State       Remote Address    Uptime
+      ipv4 1.1.1.1         OPERATIONAL 1.1.1.1         00:01:37
+      west-vm#
+
+.. index:: show mpls ldp neighbor [A.B.C.D] capabilities
+.. clicmd:: show mpls ldp neighbor [A.B.C.D] capabilities
+
+.. index:: show mpls ldp neighbor [A.B.C.D] detail
+.. clicmd:: show mpls ldp neighbor [A.B.C.D] detail
+
+   Above commands dump other neighbor information.
+
+.. index:: show mpls ldp discovery [detail]
+.. clicmd:: show mpls ldp discovery [detail]
+
+.. index:: show mpls ldp ipv4 discovery [detail]
+.. clicmd:: show mpls ldp ipv4 discovery [detail]
+
+.. index:: show mpls ldp ipv6 discovery [detail]
+.. clicmd:: show mpls ldp ipv6 discovery [detail]
+
+   Above commands dump discovery information.
+
+.. index:: show mpls ldp ipv4 interface
+.. clicmd:: show mpls ldp ipv4 interface
+
+.. index:: show mpls ldp ipv6 interface
+.. clicmd:: show mpls ldp ipv6 interface
+
+   Above command dumps the IPv4 or IPv6 interface per where LDP is enabled.
+   Below output illustrates what is dumped for IPv4.
+
+   ::
+
+      west-vm# show mpls ldp ipv4 interface
+      AF   Interface   State  Uptime   Hello Timers  ac
+      ipv4 eth1       ACTIVE 00:08:35 5/15           0
+      ipv4 eth3       ACTIVE 00:08:35 5/15           1
+
+
+.. index:: show mpls ldp ipv4|ipv6 binding
+.. clicmd:: show mpls ldp ipv4|ipv6 binding
+
+   Above command dumps the binding obtained through MPLS exchanges with LDP.
+
+   ::
+
+      west-vm# show mpls ldp ipv4 binding
+      AF   Destination          Nexthop         Local Label Remote Label  In Use
+      ipv4 1.1.1.1/32           1.1.1.1         16          imp-null         yes
+      ipv4 2.2.2.2/32           1.1.1.1         imp-null    16                no
+      ipv4 10.0.2.0/24          1.1.1.1         imp-null    imp-null          no
+      ipv4 10.115.0.0/24        1.1.1.1         imp-null    17                no
+      ipv4 10.135.0.0/24        1.1.1.1         imp-null    imp-null          no
+      ipv4 10.200.0.0/24        1.1.1.1         17          imp-null         yes
+      west-vm#
+
+LDP debugging commands
+========================
+
+.. index::
+   simple: debug mpls ldp KIND
+   simple: no debug mpls ldp KIND
+
+.. clicmd:: [no] debug mpls ldp KIND
+
+   Enable or disable debugging messages of a given kind. ``KIND`` can
+   be one of:
+
+   - ``discovery``
+   - ``errors``
+   - ``event``
+   - ``labels``
+   - ``messages``
+   - ``zebra``
+
+LDP Example Configuration
+=========================
+
+Below configuration gives a typical MPLS configuration of a device located in a
+MPLS backbone. LDP is enabled on two interfaces and will attempt to peer with
+two neighbors with router-id set to either 1.1.1.1 or 3.3.3.3.
+
+.. code-block:: frr
+
+   mpls ldp
+    router-id 2.2.2.2
+    neighbor 1.1.1.1 password test
+    neighbor 3.3.3.3 password test
+    !
+    address-family ipv4
+     discovery transport-address 2.2.2.2
+     !
+     interface eth1
+     !
+     interface eth3
+     !
+    exit-address-family
+    !
+
+
+Deploying LDP across a backbone generally is done in a full mesh configuration
+topology. LDP is typically deployed with an IGP like OSPF, that helps discover
+the remote IPs. Below example is an OSPF configuration extract that goes with
+LDP configuration
+
+.. code-block:: frr
+
+   router ospf
+    ospf router-id 2.2.2.2
+     network 0.0.0.0/0 area 0
+    !
+
+
+Below output shows the routing entry on the LER side. The OSPF routing entry
+(10.200.0.0) is associated with Label entry (17), and shows that MPLS push action
+that traffic to that destination will be applied.
+
+::
+
+   north-vm# show ip route
+   Codes: K - kernel route, C - connected, S - static, R - RIP,
+          O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+          T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+          F - PBR,
+          > - selected route, * - FIB route
+
+   O>* 1.1.1.1/32 [110/120] via 10.115.0.1, eth2, label 16, 00:00:15
+   O>* 2.2.2.2/32 [110/20] via 10.115.0.1, eth2, label implicit-null, 00:00:15
+   O   3.3.3.3/32 [110/10] via 0.0.0.0, loopback1 onlink, 00:01:19
+   C>* 3.3.3.3/32 is directly connected, loopback1, 00:01:29
+   O>* 10.0.2.0/24 [110/11] via 10.115.0.1, eth2, label implicit-null, 00:00:15
+   O   10.100.0.0/24 [110/10] is directly connected, eth1, 00:00:32
+   C>* 10.100.0.0/24 is directly connected, eth1, 00:00:32
+   O   10.115.0.0/24 [110/10] is directly connected, eth2, 00:00:25
+   C>* 10.115.0.0/24 is directly connected, eth2, 00:00:32
+   O>* 10.135.0.0/24 [110/110] via 10.115.0.1, eth2, label implicit-null, 00:00:15
+   O>* 10.200.0.0/24 [110/210] via 10.115.0.1, eth2, label 17, 00:00:15
+   north-vm#
+
index f8df33d3ee99df7f2afa07d7f21cd7380cc8021c..d51f31ff3728d7055848e5ee27cba29675c77ec9 100644 (file)
@@ -638,7 +638,7 @@ int isis_circuit_up(struct isis_circuit *circuit)
                        thread_add_timer(master, isis_run_dr_l2, circuit,
                                         2 * circuit->hello_interval[1],
                                         &circuit->u.bc.t_run_dr[1]);
-       } else {
+       } else if (circuit->circ_type == CIRCUIT_T_P2P) {
                /* initializing the hello send threads
                 * for a ptp IF
                 */
@@ -682,9 +682,6 @@ int isis_circuit_up(struct isis_circuit *circuit)
 
 void isis_circuit_down(struct isis_circuit *circuit)
 {
-       if (circuit->state != C_STATE_UP)
-               return;
-
        /* Clear the flags for all the lsps of the circuit. */
        isis_circuit_update_all_srmflags(circuit, 0);
 
@@ -756,10 +753,12 @@ void isis_circuit_down(struct isis_circuit *circuit)
        }
 
        /* send one gratuitous hello to spead up convergence */
-       if (circuit->is_type & IS_LEVEL_1)
-               send_hello(circuit, IS_LEVEL_1);
-       if (circuit->is_type & IS_LEVEL_2)
-               send_hello(circuit, IS_LEVEL_2);
+       if (circuit->state == C_STATE_UP) {
+               if (circuit->is_type & IS_LEVEL_1)
+                       send_hello(circuit, IS_LEVEL_1);
+               if (circuit->is_type & IS_LEVEL_2)
+                       send_hello(circuit, IS_LEVEL_2);
+       }
 
        circuit->upadjcount[0] = 0;
        circuit->upadjcount[1] = 0;
index d92207d57c6b7a60dcc7e6958c4102869b2482b7..3c2cf7b3fcb50f13b01029628ff22db87a1f9ed3 100644 (file)
@@ -50,7 +50,7 @@
 #include "isis_routemap.h"
 
 static route_map_result_t route_match_ip_address(void *rule,
-                                                struct prefix *prefix,
+                                                const struct prefix *prefix,
                                                 route_map_object_t type,
                                                 void *object)
 {
@@ -83,7 +83,7 @@ static struct route_map_rule_cmd route_match_ip_address_cmd = {
 /* ------------------------------------------------------------*/
 
 static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
                                   route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -116,7 +116,7 @@ struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
 /* ------------------------------------------------------------*/
 
 static route_map_result_t route_match_ipv6_address(void *rule,
-                                                  struct prefix *prefix,
+                                                  const struct prefix *prefix,
                                                   route_map_object_t type,
                                                   void *object)
 {
@@ -149,7 +149,7 @@ static struct route_map_rule_cmd route_match_ipv6_address_cmd = {
 /* ------------------------------------------------------------*/
 
 static route_map_result_t
-route_match_ipv6_address_prefix_list(void *rule, struct prefix *prefix,
+route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
                                     route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -181,7 +181,8 @@ struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = {
 
 /* ------------------------------------------------------------*/
 
-static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_metric(void *rule,
+                                          const struct prefix *prefix,
                                           route_map_object_t type,
                                           void *object)
 {
index 6c86582960365e956e8e6f741e9e1ebb1d9b5dda..d77a3e7e9351bd1b0775d1a7103859d2be82586b 100644 (file)
@@ -861,6 +861,7 @@ ldp_vty_init (void)
        install_element(LDP_IPV6_NODE, &ldp_label_remote_accept_cmd);
        install_element(LDP_IPV6_NODE, &ldp_ttl_security_disable_cmd);
        install_element(LDP_IPV6_NODE, &ldp_interface_cmd);
+       install_element(LDP_IPV6_NODE, &no_ldp_interface_cmd);
        install_element(LDP_IPV6_NODE, &ldp_session_holdtime_cmd);
        install_element(LDP_IPV6_NODE, &ldp_neighbor_ipv6_targeted_cmd);
        install_element(LDP_IPV6_NODE, &ldp_exit_address_family_cmd);
index 773a52e742eb20bb1adb93b31116f541c6b7e430..b19c33f65e6b3de860ae46f58e791429c67b4c65 100644 (file)
@@ -76,6 +76,7 @@
 
 #else
 #define CPP_WARN(text)
+#define CPP_NOTICE(text)
 #endif
 
 #endif /* _FRR_COMPILER_H */
index 5f391aa7670435486d46e773b1ad96ac8de70b19..0528b0f2ad908ffcb8e9813a62728c5179bb1f67 100644 (file)
@@ -157,7 +157,7 @@ static const char *filter_type_str(struct filter *filter)
 }
 
 /* If filter match to the prefix then return 1. */
-static int filter_match_cisco(struct filter *mfilter, struct prefix *p)
+static int filter_match_cisco(struct filter *mfilter, const struct prefix *p)
 {
        struct filter_cisco *filter;
        struct in_addr mask;
@@ -181,7 +181,7 @@ static int filter_match_cisco(struct filter *mfilter, struct prefix *p)
 }
 
 /* If filter match to the prefix then return 1. */
-static int filter_match_zebra(struct filter *mfilter, struct prefix *p)
+static int filter_match_zebra(struct filter *mfilter, const struct prefix *p)
 {
        struct filter_zebra *filter = NULL;
 
@@ -372,10 +372,11 @@ static struct access_list *access_list_get(afi_t afi, const char *name)
 }
 
 /* Apply access list to object (which should be struct prefix *). */
-enum filter_type access_list_apply(struct access_list *access, void *object)
+enum filter_type access_list_apply(struct access_list *access,
+                                  const void *object)
 {
        struct filter *filter;
-       struct prefix *p = (struct prefix *)object;
+       const struct prefix *p = (const struct prefix *)object;
 
        if (access == NULL)
                return FILTER_DENY;
@@ -549,8 +550,7 @@ static int vty_access_list_remark_unset(struct vty *vty, afi_t afi,
                access->remark = NULL;
        }
 
-       if (access->head == NULL && access->tail == NULL
-           && access->remark == NULL)
+       if (access->head == NULL && access->tail == NULL)
                access_list_delete(access);
 
        return CMD_SUCCESS;
index c02516409be5f5c04a6653bab6644267d7e8918d..97854b1e97f54c4f5412e43e29ff39e25ccabd4a 100644 (file)
@@ -59,6 +59,7 @@ extern void access_list_reset(void);
 extern void access_list_add_hook(void (*func)(struct access_list *));
 extern void access_list_delete_hook(void (*func)(struct access_list *));
 extern struct access_list *access_list_lookup(afi_t, const char *);
-extern enum filter_type access_list_apply(struct access_list *, void *);
+extern enum filter_type access_list_apply(struct access_list *access,
+                                         const void *object);
 
 #endif /* _ZEBRA_FILTER_H */
index 1e2631ea46157157d05f406adb052cbcb9524637..cee6c1e505e54a4b565df32cec9bc49823760f71 100644 (file)
@@ -232,7 +232,7 @@ extern void list_sort(struct list *list,
  * and remove list_delete_original and the list_delete #define
  * Additionally remove list_free entirely
  */
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20181001
+#if CONFDATE > 20181001
 CPP_NOTICE("list_delete without double pointer is deprecated, please fixup")
 #endif
 
index 0c853640035a9c34d7aca1e1056e597513b51bc3..7d5671290bc75c28e056d4bde0bacb5eea476c9e 100644 (file)
@@ -85,7 +85,7 @@ struct frrmod_runtime *frrmod_load(const char *spec, const char *dir, char *err,
                *args++ = '\0';
 
        if (!strchr(name, '/')) {
-               if (!handle && execname) {
+               if (execname) {
                        snprintf(fullpath, sizeof(fullpath), "%s/%s_%s.so", dir,
                                 execname, name);
                        handle = dlopen(fullpath, RTLD_NOW | RTLD_GLOBAL);
index 056b737f540ce8895dc037082362652a81d4a8df..2b666f256fce5037cbb3c8a965e0ea76aa2a48da 100644 (file)
@@ -656,7 +656,7 @@ static const char *prefix_list_type_str(struct prefix_list_entry *pentry)
 }
 
 static int prefix_list_entry_match(struct prefix_list_entry *pentry,
-                                  struct prefix *p)
+                                  const struct prefix *p)
 {
        int ret;
 
@@ -683,14 +683,15 @@ static int prefix_list_entry_match(struct prefix_list_entry *pentry,
        return 1;
 }
 
-enum prefix_list_type prefix_list_apply_which_prefix(struct prefix_list *plist,
-                                                    struct prefix **which,
-                                                    void *object)
+enum prefix_list_type prefix_list_apply_which_prefix(
+       struct prefix_list *plist,
+       const struct prefix **which,
+       const void *object)
 {
        struct prefix_list_entry *pentry, *pbest = NULL;
 
-       struct prefix *p = (struct prefix *)object;
-       uint8_t *byte = p->u.val;
+       const struct prefix *p = (const struct prefix *)object;
+       const uint8_t *byte = p->u.val;
        size_t depth;
        size_t validbits = p->prefixlen;
        struct pltrie_table *table;
index 67e345a48550b43ac506b153f7389a8d00b7581c..fecbe0e2ce6813a2fd8e7b99f60865df0f7bfb61 100644 (file)
@@ -61,8 +61,9 @@ extern struct prefix_list *prefix_list_lookup(afi_t, const char *);
  * If it is a empty plist return a NULL pointer.
  */
 extern enum prefix_list_type
-prefix_list_apply_which_prefix(struct prefix_list *plist, struct prefix **which,
-                              void *object);
+prefix_list_apply_which_prefix(struct prefix_list *plist,
+                              const struct prefix **which,
+                              const void *object);
 #define prefix_list_apply(A, B) prefix_list_apply_which_prefix((A), NULL, (B))
 
 extern struct prefix_list *prefix_bgp_orf_lookup(afi_t, const char *);
index 056c7934540d744d50e17fbada8c88338780f56c..6c4585365a34cb3eef2aff976601a1b6b76564bb 100644 (file)
@@ -1387,7 +1387,7 @@ int route_map_delete_set(struct route_map_index *index, const char *set_name,
 
 static route_map_result_t
 route_map_apply_match(struct route_map_rule_list *match_list,
-                     struct prefix *prefix, route_map_object_t type,
+                     const struct prefix *prefix, route_map_object_t type,
                      void *object)
 {
        route_map_result_t ret = RMAP_NOMATCH;
@@ -1417,7 +1417,8 @@ route_map_apply_match(struct route_map_rule_list *match_list,
 }
 
 /* Apply route map to the object. */
-route_map_result_t route_map_apply(struct route_map *map, struct prefix *prefix,
+route_map_result_t route_map_apply(struct route_map *map,
+                                  const struct prefix *prefix,
                                   route_map_object_t type, void *object)
 {
        static int recursion = 0;
index 0aeba7e1f66d4e5627c9b1bb2641f0e289af002e..0f7c391f84e44247a67c5d4dcdac1b187dda102f 100644 (file)
@@ -87,8 +87,10 @@ struct route_map_rule_cmd {
        const char *str;
 
        /* Function for value set or match. */
-       route_map_result_t (*func_apply)(void *, struct prefix *,
-                                        route_map_object_t, void *);
+       route_map_result_t (*func_apply)(void *rule,
+                                        const struct prefix *prefix,
+                                        route_map_object_t type,
+                                        void *object);
 
        /* Compile argument and return result as void *. */
        void *(*func_compile)(const char *);
@@ -208,7 +210,7 @@ extern struct route_map *route_map_lookup_by_name(const char *name);
 
 /* Apply route map to the object. */
 extern route_map_result_t route_map_apply(struct route_map *map,
-                                         struct prefix *,
+                                         const struct prefix *prefix,
                                          route_map_object_t object_type,
                                          void *object);
 
index 11af85c663d086438a270f4879742f2c547eaef3..e808f039c623c07468df2ade9792c85648931a06 100644 (file)
@@ -133,7 +133,7 @@ struct stream_fifo {
 #define STREAM_CONCAT_REMAIN(S1, S2, size) ((size) - (S1)->endp - (S2)->endp)
 
 /* deprecated macros - do not use in new code */
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20181128
+#if CONFDATE > 20181128
 CPP_NOTICE("lib: time to remove deprecated stream.h macros")
 #endif
 #define STREAM_PNT(S)   stream_pnt((S))
index 643ad29cf865782d0e4a0f12c57248f8bcdc87c8..ca50c1e70e8578f7d09b9047ca54598b4d0b4903 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -628,7 +628,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
        }
        if (vrf->ns_ctxt != NULL) {
                ns = (struct ns *)vrf->ns_ctxt;
-               if (ns && 0 != strcmp(ns->name, pathname)) {
+               if (!strcmp(ns->name, pathname)) {
                        if (vty)
                                vty_out(vty,
                                        "VRF %u already configured with NETNS %s\n",
@@ -661,8 +661,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
        ns->vrf_ctxt = (void *)vrf;
        vrf->ns_ctxt = (void *)ns;
        /* update VRF netns NAME */
-       if (vrf)
-               strlcpy(vrf->data.l.netns_name, basename(pathname), NS_NAMSIZ);
+       strlcpy(vrf->data.l.netns_name, basename(pathname), NS_NAMSIZ);
 
        if (!ns_enable(ns, vrf_update_vrf_id)) {
                if (vty)
index 6085820393d65865809bd06760c1b70759b2eb99..fe1700f8ded5aaf79eff7b3a232d9e51c1cdac29 100644 (file)
@@ -154,7 +154,7 @@ extern struct work_queue *work_queue_new(struct thread_master *, const char *);
  * The usage of work_queue_free is being transitioned to pass
  * in the double pointer to remove use after free's.
  */
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20190205
+#if CONFDATE > 20190205
 CPP_NOTICE("work_queue_free without double pointer is deprecated, please fixup")
 #endif
 extern void work_queue_free_and_null(struct work_queue **);
index ad98b8db8776d39d7bd2f65839184e5dc4893f57..49419b3df33921eb225d375c1205789e9f520333 100644 (file)
@@ -448,6 +448,8 @@ enum zapi_iptable_notify_owner {
 /* Zebra MAC types */
 #define ZEBRA_MACIP_TYPE_STICKY                0x01 /* Sticky MAC*/
 #define ZEBRA_MACIP_TYPE_GW                    0x02 /* gateway (SVI) mac*/
+#define ZEBRA_MACIP_TYPE_ROUTER_FLAG           0x04 /* Router Flag - proxy NA */
+#define ZEBRA_MACIP_TYPE_OVERRIDE_FLAG         0x08 /* Override Flag */
 
 struct zclient_options {
        bool receive_notify;
@@ -457,7 +459,7 @@ struct zclient_options {
 extern struct zclient *zclient_new(struct thread_master *);
 
 /* clang-format off */
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20181101
+#if CONFDATE > 20181101
 CPP_NOTICE("zclient_new_notify can take over or zclient_new now");
 #endif
 /* clang-format on */
@@ -598,7 +600,7 @@ extern void zebra_interface_if_set_value(struct stream *, struct interface *);
 extern void zebra_router_id_update_read(struct stream *s, struct prefix *rid);
 
 /* clang-format off */
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180823
+#if CONFDATE > 20180823
 CPP_NOTICE("zapi_ipv4_route, zapi_ipv6_route, zapi_ipv4_route_ipv6_nexthop as well as the zapi_ipv4 and zapi_ipv6 data structures should be removed now");
 #endif
 /* clang-format on */
index a7233965077b03b703500a94bd13ac59cc89b0e5..e6bd3faf405b6712e01c21c26e7b58f2aa60d718 100644 (file)
@@ -1345,7 +1345,8 @@ static void ospf6_redistribute_show_config(struct vty *vty)
 
 /* Routemap Functions */
 static route_map_result_t
-ospf6_routemap_rule_match_address_prefixlist(void *rule, struct prefix *prefix,
+ospf6_routemap_rule_match_address_prefixlist(void *rule,
+                                            const struct prefix *prefix,
                                             route_map_object_t type,
                                             void *object)
 {
@@ -1384,7 +1385,7 @@ struct route_map_rule_cmd ospf6_routemap_rule_match_address_prefixlist_cmd = {
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t
-ospf6_routemap_rule_match_interface(void *rule, struct prefix *prefix,
+ospf6_routemap_rule_match_interface(void *rule, const struct prefix *prefix,
                                    route_map_object_t type, void *object)
 {
        struct interface *ifp;
@@ -1422,7 +1423,7 @@ struct route_map_rule_cmd ospf6_routemap_rule_match_interface_cmd = {
 
 /* Match function for matching route tags */
 static route_map_result_t ospf6_routemap_rule_match_tag(void *rule,
-                                                       struct prefix *prefix,
+                                                       const struct prefix *p,
                                                        route_map_object_t type,
                                                        void *object)
 {
@@ -1442,7 +1443,7 @@ static struct route_map_rule_cmd ospf6_routemap_rule_match_tag_cmd = {
 };
 
 static route_map_result_t
-ospf6_routemap_rule_set_metric_type(void *rule, struct prefix *prefix,
+ospf6_routemap_rule_set_metric_type(void *rule, const struct prefix *prefix,
                                    route_map_object_t type, void *object)
 {
        char *metric_type = rule;
@@ -1478,7 +1479,7 @@ struct route_map_rule_cmd ospf6_routemap_rule_set_metric_type_cmd = {
 };
 
 static route_map_result_t
-ospf6_routemap_rule_set_metric(void *rule, struct prefix *prefix,
+ospf6_routemap_rule_set_metric(void *rule, const struct prefix *prefix,
                               route_map_object_t type, void *object)
 {
        char *metric = rule;
@@ -1513,7 +1514,7 @@ struct route_map_rule_cmd ospf6_routemap_rule_set_metric_cmd = {
 };
 
 static route_map_result_t
-ospf6_routemap_rule_set_forwarding(void *rule, struct prefix *prefix,
+ospf6_routemap_rule_set_forwarding(void *rule, const struct prefix *prefix,
                                   route_map_object_t type, void *object)
 {
        char *forwarding = rule;
@@ -1551,7 +1552,7 @@ struct route_map_rule_cmd ospf6_routemap_rule_set_forwarding_cmd = {
 };
 
 static route_map_result_t ospf6_routemap_rule_set_tag(void *rule,
-                                                     struct prefix *prefix,
+                                                     const struct prefix *p,
                                                      route_map_object_t type,
                                                      void *object)
 {
index 7bf099fbbfb2dd33bc0c008e41ca7a6812e12e88..fde47c74fef9e8a148ee522de1d24f734af5cb00 100644 (file)
@@ -425,13 +425,13 @@ DEFUN(no_ospf6_router_id,
        return CMD_SUCCESS;
 }
 
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180828
+#if CONFDATE > 20180828
 CPP_NOTICE("ospf6: `router-id A.B.C.D` deprecated 2017/08/28")
 #endif
 ALIAS_HIDDEN(ospf6_router_id, ospf6_router_id_hdn_cmd, "router-id A.B.C.D",
             "Configure OSPF6 Router-ID\n" V4NOTATION_STR)
 
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180828
+#if CONFDATE > 20180828
 CPP_NOTICE("ospf6: `no router-id A.B.C.D` deprecated 2017/08/28")
 #endif
 ALIAS_HIDDEN(no_ospf6_router_id, no_ospf6_router_id_hdn_cmd,
index f3271acfa2ae1d76eb91b091e7f2eb44f5815d29..c5ec1db336a93a14a93c4777efa1ba17c4461e77 100644 (file)
@@ -118,7 +118,7 @@ static void ospf_route_map_event(route_map_event_t event, const char *name)
 /* `match ip netxthop ' */
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t route_match_ip_nexthop(void *rule,
-                                                struct prefix *prefix,
+                                                const struct prefix *prefix,
                                                 route_map_object_t type,
                                                 void *object)
 {
@@ -163,7 +163,7 @@ struct route_map_rule_cmd route_match_ip_nexthop_cmd = {
 /* `match ip next-hop prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
                                    route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -205,7 +205,7 @@ struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = {
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t route_match_ip_address(void *rule,
-                                                struct prefix *prefix,
+                                                const struct prefix *prefix,
                                                 route_map_object_t type,
                                                 void *object)
 {
@@ -244,7 +244,7 @@ struct route_map_rule_cmd route_match_ip_address_cmd = {
 
 /* `match ip address prefix-list PREFIX_LIST' */
 static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
                                   route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -280,7 +280,7 @@ struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t route_match_interface(void *rule,
-                                               struct prefix *prefix,
+                                               const struct prefix *prefix,
                                                route_map_object_t type,
                                                void *object)
 {
@@ -318,7 +318,8 @@ struct route_map_rule_cmd route_match_interface_cmd = {
        route_match_interface_free};
 
 /* Match function return 1 if match is success else return zero. */
-static route_map_result_t route_match_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_tag(void *rule,
+                                         const struct prefix *prefix,
                                          route_map_object_t type, void *object)
 {
        route_tag_t *tag;
@@ -348,7 +349,8 @@ struct ospf_metric {
 
 /* `set metric METRIC' */
 /* Set metric to attribute. */
-static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_metric(void *rule,
+                                          const struct prefix *prefix,
                                           route_map_object_t type,
                                           void *object)
 {
@@ -427,7 +429,7 @@ struct route_map_rule_cmd route_set_metric_cmd = {
 /* `set metric-type TYPE' */
 /* Set metric-type to attribute. */
 static route_map_result_t route_set_metric_type(void *rule,
-                                               struct prefix *prefix,
+                                               const struct prefix *prefix,
                                                route_map_object_t type,
                                                void *object)
 {
@@ -476,7 +478,7 @@ struct route_map_rule_cmd route_set_metric_type_cmd = {
        route_set_metric_type_free,
 };
 
-static route_map_result_t route_set_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_tag(void *rule, const struct prefix *prefix,
                                        route_map_object_t type, void *object)
 {
        route_tag_t *tag;
index ae2daf40aa709834126c393e9fd4027937ca3a60..460bbfeae71e6cffafef255ae37c429a5d9a5c1d 100644 (file)
@@ -4252,7 +4252,7 @@ DEFUN (show_ip_pim_nexthop_lookup,
        "Source/RP address\n"
        "Multicast Group address\n")
 {
-       struct pim_nexthop_cache pnc;
+       struct pim_nexthop_cache *pnc = NULL;
        struct prefix nht_p;
        int result = 0;
        struct in_addr src_addr, grp_addr;
@@ -4264,6 +4264,7 @@ DEFUN (show_ip_pim_nexthop_lookup,
        char grp_str[PREFIX_STRLEN];
        int idx = 2;
        struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+       struct pim_rpf rpf;
 
        if (!vrf)
                return CMD_WARNING;
@@ -4301,7 +4302,6 @@ DEFUN (show_ip_pim_nexthop_lookup,
                                      grp_addr))
                return CMD_SUCCESS;
 
-       memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
        nht_p.family = AF_INET;
        nht_p.prefixlen = IPV4_MAX_BITLEN;
        nht_p.u.prefix4 = vif_source;
@@ -4310,12 +4310,18 @@ DEFUN (show_ip_pim_nexthop_lookup,
        grp.u.prefix4 = grp_addr;
        memset(&nexthop, 0, sizeof(nexthop));
 
-       if (pim_find_or_track_nexthop(vrf->info, &nht_p, NULL, NULL, &pnc))
-               result = pim_ecmp_nexthop_search(vrf->info, &pnc, &nexthop,
+       memset(&rpf, 0, sizeof(struct pim_rpf));
+       rpf.rpf_addr.family = AF_INET;
+       rpf.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
+       rpf.rpf_addr.u.prefix4 = vif_source;
+
+       pnc = pim_nexthop_cache_find(vrf->info, &rpf);
+       if (pnc)
+               result = pim_ecmp_nexthop_search(vrf->info, pnc, &nexthop,
                                                 &nht_p, &grp, 0);
        else
-               result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop,
-                                                vif_source, &nht_p, &grp, 0);
+               result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p,
+                                                &grp, 0);
 
        if (!result) {
                vty_out(vty,
index e82a7589b719a72447cbf1fcff1fbfffbf2cdbd2..eb3307589ec0b826e8470974157a3385c44dd77a 100644 (file)
@@ -136,9 +136,8 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
                        mask = PIM_OIF_FLAG_PROTO_IGMP;
 
                /* SGRpt entry could have empty oil */
-               if (ch->upstream->channel_oil)
-                       pim_channel_del_oif(ch->upstream->channel_oil,
-                                           ch->interface, mask);
+               pim_channel_del_oif(ch->upstream->channel_oil, ch->interface,
+                                   mask);
                /*
                 * Do we have any S,G's that are inheriting?
                 * Nuke from on high too.
index 42bdd80ce226614b4653865dc377c7efbcf3a4a9..b46f1b5e9dde1870297c7fcb633d64bcc2a3fa83 100644 (file)
@@ -909,10 +909,9 @@ static int pim_igmp_read(struct thread *t)
        socklen_t fromlen = sizeof(from);
        socklen_t tolen = sizeof(to);
        ifindex_t ifindex = -1;
-       int cont = 1;
        int len;
 
-       while (cont) {
+       while (1) {
                len = pim_socket_recvfromto(igmp->fd, buf, sizeof(buf), &from,
                                            &fromlen, &to, &tolen, &ifindex);
                if (len < 0) {
index ac49373da07a07fccc7c1508ebcc7b91c4983b7a..7d1940bec1c07c3e4b0978d2b68d5274981133fb 100644 (file)
@@ -418,16 +418,21 @@ int pim_ecmp_nexthop_search(struct pim_instance *pim,
                            struct pim_nexthop *nexthop, struct prefix *src,
                            struct prefix *grp, int neighbor_needed)
 {
-       struct pim_neighbor *nbr = NULL;
+       struct pim_neighbor *nbrs[MULTIPATH_NUM], *nbr;
+       struct interface *ifps[MULTIPATH_NUM];
        struct nexthop *nh_node = NULL;
        ifindex_t first_ifindex;
        struct interface *ifp = NULL;
        uint32_t hash_val = 0, mod_val = 0;
        uint8_t nh_iter = 0, found = 0;
+       uint32_t i, num_nbrs = 0;
 
        if (!pnc || !pnc->nexthop_num || !nexthop)
                return 0;
 
+       memset(&nbrs, 0, sizeof(nbrs));
+       memset(&ifps, 0, sizeof(ifps));
+
        // Current Nexthop is VALID, check to stay on the current path.
        if (nexthop->interface && nexthop->interface->info
            && nexthop->mrib_nexthop_addr.u.prefix4.s_addr
@@ -487,16 +492,41 @@ int pim_ecmp_nexthop_search(struct pim_instance *pim,
                        }
                }
        }
+
+       /*
+        * Look up all interfaces and neighbors,
+        * store for later usage
+        */
+       for (nh_node = pnc->nexthop, i = 0; nh_node;
+            nh_node = nh_node->next, i++) {
+               ifps[i] = if_lookup_by_index(nh_node->ifindex, pim->vrf_id);
+               if (ifps[i]) {
+                       nbrs[i] = pim_neighbor_find(ifps[i],
+                                                   nh_node->gate.ipv4);
+                       if (nbrs[i] || pim_if_connected_to_source(ifps[i],
+
+                                                                 src->u.prefix4))
+                               num_nbrs++;
+               }
+       }
        if (pim->ecmp_enable) {
+               uint32_t consider = pnc->nexthop_num;
+
+               if (neighbor_needed && num_nbrs < consider)
+                       consider = num_nbrs;
+
+               if (consider == 0)
+                       return 0;
+
                // PIM ECMP flag is enable then choose ECMP path.
                hash_val = pim_compute_ecmp_hash(src, grp);
-               mod_val = hash_val % pnc->nexthop_num;
+               mod_val = hash_val % consider;
        }
 
        for (nh_node = pnc->nexthop; nh_node && (found == 0);
             nh_node = nh_node->next) {
                first_ifindex = nh_node->ifindex;
-               ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
+               ifp = ifps[nh_iter];
                if (!ifp) {
                        if (PIM_DEBUG_PIM_NHT) {
                                char addr_str[INET_ADDRSTRLEN];
@@ -532,7 +562,7 @@ int pim_ecmp_nexthop_search(struct pim_instance *pim,
 
                if (neighbor_needed
                    && !pim_if_connected_to_source(ifp, src->u.prefix4)) {
-                       nbr = pim_neighbor_find(ifp, nh_node->gate.ipv4);
+                       nbr = nbrs[nh_iter];
                        if (!nbr && !if_is_loopback(ifp)) {
                                if (PIM_DEBUG_PIM_NHT)
                                        zlog_debug(
@@ -767,22 +797,23 @@ int pim_parse_nexthop_update(int command, struct zclient *zclient,
 }
 
 int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
-                           struct pim_nexthop *nexthop, struct in_addr addr,
-                           struct prefix *src, struct prefix *grp,
-                           int neighbor_needed)
+                           struct pim_nexthop *nexthop, struct prefix *src,
+                           struct prefix *grp, int neighbor_needed)
 {
        struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
-       struct pim_neighbor *nbr = NULL;
+       struct pim_neighbor *nbrs[MULTIPATH_NUM], *nbr = NULL;
        int num_ifindex;
-       struct interface *ifp;
+       struct interface *ifps[MULTIPATH_NUM], *ifp;
        int first_ifindex;
        int found = 0;
        uint8_t i = 0;
        uint32_t hash_val = 0, mod_val = 0;
+       uint32_t num_nbrs = 0;
+       char addr_str[PREFIX_STRLEN];
 
        if (PIM_DEBUG_PIM_NHT) {
-               char addr_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+               pim_inet4_dump("<addr?>", src->u.prefix4, addr_str,
+                              sizeof(addr_str));
                zlog_debug("%s: Looking up: %s(%s), last lookup time: %lld",
                           __PRETTY_FUNCTION__, addr_str, pim->vrf->name,
                           nexthop->last_lookup_time);
@@ -790,44 +821,66 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
 
        memset(nexthop_tab, 0,
               sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM);
-       num_ifindex = zclient_lookup_nexthop(pim, nexthop_tab, MULTIPATH_NUM,
-                                            addr, PIM_NEXTHOP_LOOKUP_MAX);
+       num_ifindex =
+               zclient_lookup_nexthop(pim, nexthop_tab, MULTIPATH_NUM,
+                                      src->u.prefix4, PIM_NEXTHOP_LOOKUP_MAX);
        if (num_ifindex < 1) {
-               if (PIM_DEBUG_PIM_NHT) {
-                       char addr_str[INET_ADDRSTRLEN];
-                       pim_inet4_dump("<addr?>", addr, addr_str,
-                                      sizeof(addr_str));
+               if (PIM_DEBUG_PIM_NHT)
                        zlog_warn(
                                "%s: could not find nexthop ifindex for address %s(%s)",
                                __PRETTY_FUNCTION__, addr_str, pim->vrf->name);
-               }
                return 0;
        }
 
+       memset(&nbrs, 0, sizeof(nbrs));
+       memset(&ifps, 0, sizeof(ifps));
+
+       /*
+        * Look up all interfaces and neighbors,
+        * store for later usage
+        */
+       for (i = 0; i < num_ifindex; i++) {
+               ifps[i] = if_lookup_by_index(nexthop_tab[i].ifindex,
+                                            pim->vrf_id);
+               if (ifps[i]) {
+                       nbrs[i] = pim_neighbor_find(
+                               ifps[i], nexthop_tab[i].nexthop_addr.u.prefix4);
+                       if (nbrs[i]
+                           || pim_if_connected_to_source(ifps[i],
+                                                         src->u.prefix4))
+                               num_nbrs++;
+               }
+       }
+
        // If PIM ECMP enable then choose ECMP path.
        if (pim->ecmp_enable) {
+               uint32_t consider = num_ifindex;
+
+               if (neighbor_needed && num_nbrs < consider)
+                       consider = num_nbrs;
+
+               if (consider == 0)
+                       return 0;
+
                hash_val = pim_compute_ecmp_hash(src, grp);
-               mod_val = hash_val % num_ifindex;
+               mod_val = hash_val % consider;
                if (PIM_DEBUG_PIM_NHT_DETAIL)
                        zlog_debug("%s: hash_val %u mod_val %u",
                                   __PRETTY_FUNCTION__, hash_val, mod_val);
        }
 
+       i = 0;
        while (!found && (i < num_ifindex)) {
                first_ifindex = nexthop_tab[i].ifindex;
 
-               ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
+               ifp = ifps[i];
                if (!ifp) {
-                       if (PIM_DEBUG_PIM_NHT) {
-                               char addr_str[INET_ADDRSTRLEN];
-                               pim_inet4_dump("<addr?>", addr, addr_str,
-                                              sizeof(addr_str));
+                       if (PIM_DEBUG_PIM_NHT)
                                zlog_debug(
                                        "%s %s: could not find interface for ifindex %d (address %s(%s))",
                                        __FILE__, __PRETTY_FUNCTION__,
                                        first_ifindex, addr_str,
                                        pim->vrf->name);
-                       }
                        if (i == mod_val)
                                mod_val++;
                        i++;
@@ -835,24 +888,20 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
                }
 
                if (!ifp->info) {
-                       if (PIM_DEBUG_PIM_NHT) {
-                               char addr_str[INET_ADDRSTRLEN];
-                               pim_inet4_dump("<addr?>", addr, addr_str,
-                                              sizeof(addr_str));
+                       if (PIM_DEBUG_PIM_NHT)
                                zlog_debug(
                                        "%s: multicast not enabled on input interface %s(%s) (ifindex=%d, RPF for source %s)",
                                        __PRETTY_FUNCTION__, ifp->name,
                                        pim->vrf->name, first_ifindex,
                                        addr_str);
-                       }
                        if (i == mod_val)
                                mod_val++;
                        i++;
                        continue;
                }
-               if (neighbor_needed && !pim_if_connected_to_source(ifp, addr)) {
-                       nbr = pim_neighbor_find(
-                               ifp, nexthop_tab[i].nexthop_addr.u.prefix4);
+               if (neighbor_needed
+                   && !pim_if_connected_to_source(ifp, src->u.prefix4)) {
+                       nbr = nbrs[i];
                        if (PIM_DEBUG_PIM_NHT_DETAIL)
                                zlog_debug("ifp name: %s(%s), pim nbr: %p",
                                           ifp->name, pim->vrf->name, nbr);
@@ -860,16 +909,11 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
                                if (i == mod_val)
                                        mod_val++;
                                i++;
-                               if (PIM_DEBUG_PIM_NHT) {
-                                       char addr_str[INET_ADDRSTRLEN];
-                                       pim_inet4_dump("<addr?>", addr,
-                                                      addr_str,
-                                                      sizeof(addr_str));
+                               if (PIM_DEBUG_PIM_NHT)
                                        zlog_debug(
                                                "%s: NBR not found on input interface %s(%s) (RPF for source %s)",
                                                __PRETTY_FUNCTION__, ifp->name,
                                                pim->vrf->name, addr_str);
-                               }
                                continue;
                        }
                }
@@ -877,12 +921,10 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
                if (i == mod_val) {
                        if (PIM_DEBUG_PIM_NHT) {
                                char nexthop_str[PREFIX_STRLEN];
-                               char addr_str[INET_ADDRSTRLEN];
+
                                pim_addr_dump("<nexthop?>",
                                              &nexthop_tab[i].nexthop_addr,
                                              nexthop_str, sizeof(nexthop_str));
-                               pim_inet4_dump("<addr?>", addr, addr_str,
-                                              sizeof(addr_str));
                                zlog_debug(
                                        "%s: found nhop %s for addr %s interface %s(%s) metric %d dist %d",
                                        __PRETTY_FUNCTION__, nexthop_str,
@@ -898,7 +940,7 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
                                nexthop_tab[i].protocol_distance;
                        nexthop->mrib_route_metric =
                                nexthop_tab[i].route_metric;
-                       nexthop->last_lookup = addr;
+                       nexthop->last_lookup = src->u.prefix4;
                        nexthop->last_lookup_time = pim_time_monotonic_usec();
                        nexthop->nbr = nbr;
                        found = 1;
@@ -913,59 +955,36 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
 }
 
 int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
-                                    struct in_addr addr, struct prefix *src,
-                                    struct prefix *grp)
+                                    struct prefix *src, struct prefix *grp)
 {
-       struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
-       int num_ifindex;
+       struct pim_nexthop nhop;
        int vif_index;
-       ifindex_t first_ifindex;
-       uint32_t hash_val = 0, mod_val = 0;
+       ifindex_t ifindex;
+       char addr_str[PREFIX_STRLEN];
 
-       memset(nexthop_tab, 0,
-              sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM);
-       num_ifindex = zclient_lookup_nexthop(pim, nexthop_tab, MULTIPATH_NUM,
-                                            addr, PIM_NEXTHOP_LOOKUP_MAX);
-       if (num_ifindex < 1) {
-               if (PIM_DEBUG_PIM_NHT) {
-                       char addr_str[INET_ADDRSTRLEN];
-                       pim_inet4_dump("<addr?>", addr, addr_str,
-                                      sizeof(addr_str));
+       if (PIM_DEBUG_PIM_NHT)
+               pim_inet4_dump("<addr?>", src->u.prefix4, addr_str,
+                              sizeof(addr_str));
+       if (!pim_ecmp_nexthop_lookup(pim, &nhop, src, grp, 0)) {
+               if (PIM_DEBUG_PIM_NHT)
                        zlog_debug(
                                "%s: could not find nexthop ifindex for address %s(%s)",
                                __PRETTY_FUNCTION__, addr_str, pim->vrf->name);
-               }
                return -1;
        }
 
-       // If PIM ECMP enable then choose ECMP path.
-       if (pim->ecmp_enable) {
-               hash_val = pim_compute_ecmp_hash(src, grp);
-               mod_val = hash_val % num_ifindex;
-               if (PIM_DEBUG_PIM_NHT_DETAIL)
-                       zlog_debug("%s: hash_val %u mod_val %u",
-                                  __PRETTY_FUNCTION__, hash_val, mod_val);
-       }
-
-       first_ifindex = nexthop_tab[mod_val].ifindex;
-
-       if (PIM_DEBUG_PIM_NHT) {
-               char addr_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<ifaddr?>", addr, addr_str, sizeof(addr_str));
+       ifindex = nhop.interface->ifindex;
+       if (PIM_DEBUG_PIM_NHT)
                zlog_debug(
                        "%s: found nexthop ifindex=%d (interface %s(%s)) for address %s",
-                       __PRETTY_FUNCTION__, first_ifindex,
-                       ifindex2ifname(first_ifindex, pim->vrf_id),
+                       __PRETTY_FUNCTION__, ifindex,
+                       ifindex2ifname(ifindex, pim->vrf_id),
                        pim->vrf->name, addr_str);
-       }
 
-       vif_index = pim_if_find_vifindex_by_ifindex(pim, first_ifindex);
+       vif_index = pim_if_find_vifindex_by_ifindex(pim, ifindex);
 
        if (vif_index < 0) {
                if (PIM_DEBUG_PIM_NHT) {
-                       char addr_str[INET_ADDRSTRLEN];
-                       pim_inet4_dump("<addr?>", addr, addr_str,
-                                      sizeof(addr_str));
                        zlog_debug(
                                "%s: low vif_index=%d(%s) < 1 nexthop for address %s",
                                __PRETTY_FUNCTION__, vif_index, pim->vrf->name,
index 77e25dcd7095a9a5243c1cf32505a0037da8b911..796fbf9731943f2ca58278527ba516341455d630 100644 (file)
@@ -61,13 +61,11 @@ int pim_ecmp_nexthop_search(struct pim_instance *pim,
                            struct pim_nexthop *nexthop, struct prefix *src,
                            struct prefix *grp, int neighbor_needed);
 int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
-                           struct pim_nexthop *nexthop, struct in_addr addr,
-                           struct prefix *src, struct prefix *grp,
-                           int neighbor_needed);
+                           struct pim_nexthop *nexthop, struct prefix *src,
+                           struct prefix *grp, int neighbor_needed);
 void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
                           struct pim_nexthop_cache *pnc, int command);
 void pim_resolve_upstream_nh(struct pim_instance *pim, struct prefix *nht_p);
 int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
-                                    struct in_addr addr, struct prefix *src,
-                                    struct prefix *grp);
+                                    struct prefix *src, struct prefix *grp);
 #endif
index 7e053d2aa01c36c8293951dbe99900a59bd2c049..c1623ec15e7ebd6779e3d409786418e07dff96cd 100644 (file)
@@ -194,7 +194,7 @@ static int pim_rp_prefix_list_used(struct pim_instance *pim, const char *plist)
  */
 static struct rp_info *pim_rp_find_exact(struct pim_instance *pim,
                                         struct in_addr rp,
-                                        struct prefix *group)
+                                        const struct prefix *group)
 {
        struct listnode *node;
        struct rp_info *rp_info;
@@ -212,13 +212,13 @@ static struct rp_info *pim_rp_find_exact(struct pim_instance *pim,
  * Given a group, return the rp_info for that group
  */
 static struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
-                                              struct prefix *group)
+                                              const struct prefix *group)
 {
        struct listnode *node;
        struct rp_info *best = NULL;
        struct rp_info *rp_info;
        struct prefix_list *plist;
-       struct prefix *p, *bp;
+       const struct prefix *p, *bp;
        struct route_node *rn;
 
        bp = NULL;
@@ -477,10 +477,9 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
                                            &rp_all->group, 1))
                                        return PIM_RP_NO_PATH;
                        } else {
-                               if (pim_nexthop_lookup(
+                               if (!pim_ecmp_nexthop_lookup(
                                            pim, &rp_all->rp.source_nexthop,
-                                           rp_all->rp.rpf_addr.u.prefix4, 1)
-                                   != 0)
+                                           &nht_p, &rp_all->group, 1))
                                        return PIM_RP_NO_PATH;
                        }
                        pim_rp_check_interfaces(pim, rp_all);
@@ -556,9 +555,8 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
                                             &nht_p, &rp_info->group, 1))
                        return PIM_RP_NO_PATH;
        } else {
-               if (pim_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
-                                      rp_info->rp.rpf_addr.u.prefix4, 1)
-                   != 0)
+               if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
+                                            &nht_p, &rp_info->group, 1))
                        return PIM_RP_NO_PATH;
        }
 
@@ -687,9 +685,9 @@ void pim_rp_setup(struct pim_instance *pim)
                                        "%s: NHT Local Nexthop not found for RP %s ",
                                        __PRETTY_FUNCTION__, buf);
                        }
-                       if (pim_nexthop_lookup(
-                                   pim, &rp_info->rp.source_nexthop,
-                                   rp_info->rp.rpf_addr.u.prefix4, 1) < 0)
+                       if (!pim_ecmp_nexthop_lookup(pim,
+                                                    &rp_info->rp.source_nexthop,
+                                                     &nht_p, &rp_info->group, 1))
                                if (PIM_DEBUG_PIM_NHT_RP)
                                        zlog_debug(
                                                "Unable to lookup nexthop for rp specified");
@@ -854,8 +852,9 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group)
                                        __PRETTY_FUNCTION__, buf, buf1);
                        }
                        pim_rpf_set_refresh_time(pim);
-                       pim_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
-                                          rp_info->rp.rpf_addr.u.prefix4, 1);
+                       pim_ecmp_nexthop_lookup(pim,
+                                               &rp_info->rp.source_nexthop,
+                                               &nht_p, &rp_info->group, 1);
                }
                return (&rp_info->rp);
        }
index da14e8b3eb9528f6d0884ffa9c483683efd9cfec..b02102c8fd88c80f671ec589e9e562e3bd967070 100644 (file)
@@ -203,6 +203,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
        struct prefix nht_p;
        struct pim_nexthop_cache pnc;
        struct prefix src, grp;
+       bool neigh_needed = true;
 
        saved.source_nexthop = rpf->source_nexthop;
        saved.rpf_addr = rpf->rpf_addr;
@@ -226,23 +227,20 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
        grp.prefixlen = IPV4_MAX_BITLEN;
        grp.u.prefix4 = up->sg.grp;
        memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
+
+       if ((up->sg.src.s_addr == INADDR_ANY && I_am_RP(pim, up->sg.grp)) ||
+           PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
+               neigh_needed = FALSE;
        if (pim_find_or_track_nexthop(pim, &nht_p, up, NULL, &pnc)) {
                if (pnc.nexthop_num) {
-                       if (!pim_ecmp_nexthop_search(
-                                   pim, &pnc, &up->rpf.source_nexthop, &src,
-                                   &grp,
-                                   !PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)
-                                           && !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(
-                                                      up->flags)))
+                       if (!pim_ecmp_nexthop_search(pim, &pnc,
+                                                    &up->rpf.source_nexthop,
+                                                    &src, &grp, neigh_needed))
                                return PIM_RPF_FAILURE;
                }
        } else {
-               if (!pim_ecmp_nexthop_lookup(
-                           pim, &rpf->source_nexthop, up->upstream_addr, &src,
-                           &grp,
-                           !PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)
-                                   && !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(
-                                              up->flags)))
+               if (!pim_ecmp_nexthop_lookup(pim, &rpf->source_nexthop, &src,
+                                            &grp, neigh_needed))
                        return PIM_RPF_FAILURE;
        }
 
index a58dfcdd5f0e5bc85e34b5f66b336fa3a15d1e7e..b947ca06256b1d8c52740ed67932e0cc230ba94d 100644 (file)
@@ -561,7 +561,7 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
                                __PRETTY_FUNCTION__, source_str, group_str);
                }
                input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(
-                       c_oil->pim, vif_source, &src, &grp);
+                       c_oil->pim, &src, &grp);
        }
 
        if (input_iface_vif_index < 1) {
@@ -868,6 +868,7 @@ void igmp_source_forward_reevaluate_all(struct pim_instance *pim)
 void igmp_source_forward_start(struct pim_instance *pim,
                               struct igmp_source *source)
 {
+       struct pim_interface *pim_oif;
        struct igmp_group *group;
        struct prefix_sg sg;
        int result;
@@ -893,10 +894,20 @@ void igmp_source_forward_start(struct pim_instance *pim,
        }
 
        group = source->source_group;
+       pim_oif = group->group_igmp_sock->interface->info;
+       if (!pim_oif) {
+               if (PIM_DEBUG_IGMP_TRACE) {
+                       zlog_debug(
+                                  "%s: multicast not enabled on oif=%s ?",
+                                  __PRETTY_FUNCTION__,
+                                  source->source_group->group_igmp_sock
+                                  ->interface->name);
+               }
+               return;
+       }
 
        if (!source->source_channel_oil) {
                struct in_addr vif_source;
-               struct pim_interface *pim_oif;
                struct prefix nht_p, src, grp;
                struct pim_nexthop_cache out_pnc;
                struct pim_nexthop nexthop;
@@ -953,8 +964,8 @@ void igmp_source_forward_start(struct pim_instance *pim,
                        }
                } else
                        input_iface_vif_index =
-                               pim_ecmp_fib_lookup_if_vif_index(
-                                       pim, vif_source, &src, &grp);
+                               pim_ecmp_fib_lookup_if_vif_index(pim, &src,
+                                                                &grp);
 
                if (PIM_DEBUG_ZEBRA) {
                        char buf2[INET_ADDRSTRLEN];
@@ -983,19 +994,6 @@ void igmp_source_forward_start(struct pim_instance *pim,
                  source and receiver attached to the same interface. See TODO
                  T22.
                */
-               pim_oif =
-                       source->source_group->group_igmp_sock->interface->info;
-               if (!pim_oif) {
-                       if (PIM_DEBUG_IGMP_TRACE) {
-                               zlog_debug(
-                                       "%s: multicast not enabled on oif=%s ?",
-                                       __PRETTY_FUNCTION__,
-                                       source->source_group->group_igmp_sock
-                                               ->interface->name);
-                       }
-                       return;
-               }
-
                if (input_iface_vif_index == pim_oif->mroute_vif_index) {
                        /* ignore request for looped MFC entry */
                        if (PIM_DEBUG_IGMP_TRACE) {
@@ -1036,12 +1034,15 @@ void igmp_source_forward_start(struct pim_instance *pim,
                return;
        }
 
+       if (!(PIM_I_am_DR(pim_oif)))
+               return;
+
        /*
          Feed IGMPv3-gathered local membership information into PIM
          per-interface (S,G) state.
         */
        if (!pim_ifchannel_local_membership_add(
-                   group->group_igmp_sock->interface, &sg)) {
+                                               group->group_igmp_sock->interface, &sg)) {
                if (PIM_DEBUG_MROUTE)
                        zlog_warn("%s: Failure to add local membership for %s",
                                  __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
@@ -1153,7 +1154,7 @@ void pim_forward_start(struct pim_ifchannel *ch)
                /* Register addr with Zebra NHT */
                nht_p.family = AF_INET;
                nht_p.prefixlen = IPV4_MAX_BITLEN;
-               nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
+               nht_p.u.prefix4 = up->upstream_addr;
                grp.family = AF_INET;
                grp.prefixlen = IPV4_MAX_BITLEN;
                grp.u.prefix4 = up->sg.grp;
@@ -1204,8 +1205,8 @@ void pim_forward_start(struct pim_ifchannel *ch)
                        }
                } else
                        input_iface_vif_index =
-                               pim_ecmp_fib_lookup_if_vif_index(
-                                       pim, up->upstream_addr, &src, &grp);
+                               pim_ecmp_fib_lookup_if_vif_index(pim, &src,
+                                                                &grp);
 
                if (input_iface_vif_index < 1) {
                        if (PIM_DEBUG_PIM_TRACE) {
index e2be7050d7ad98f406d79b4ae90ae14401f27aa5..85fb309048e9bfc4fe220cd9d425d02cebc51fb1 100644 (file)
@@ -370,6 +370,10 @@ ln -s %{_sbindir}/frr %{buildroot}%{_initddir}/frr
 %endif
 
 install %{zeb_rh_src}/daemons %{buildroot}%{_sysconfdir}/frr
+# add rpki module to daemon
+%if %{with_rpki}
+    sed -i -e 's/^\(bgpd_options=\)\(.*\)\(".*\)/\1\2 -M rpki\3/' %{buildroot}%{_sysconfdir}/frr/daemons
+%endif
 install -m644 %{zeb_rh_src}/frr.pam %{buildroot}%{_sysconfdir}/pam.d/frr
 install -m644 %{zeb_rh_src}/frr.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/frr
 install -d -m750 %{buildroot}%{rundir}
index 2c02324876744610215102644735a00032854382..88473c164e1b24442e40cdec2783b57b9a2b62c0 100644 (file)
@@ -58,7 +58,8 @@ static void rip_route_map_update(const char *notused)
 
 /* `match metric METRIC' */
 /* Match function return 1 if match is success else return zero. */
-static route_map_result_t route_match_metric(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_metric(void *rule,
+                                            const struct prefix *prefix,
                                             route_map_object_t type,
                                             void *object)
 {
@@ -111,7 +112,7 @@ struct route_map_rule_cmd route_match_metric_cmd = {
 /* `match interface IFNAME' */
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t route_match_interface(void *rule,
-                                               struct prefix *prefix,
+                                               const struct prefix *prefix,
                                                route_map_object_t type,
                                                void *object)
 {
@@ -159,7 +160,7 @@ struct route_map_rule_cmd route_match_interface_cmd = {
 
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t route_match_ip_next_hop(void *rule,
-                                                 struct prefix *prefix,
+                                                 const struct prefix *prefix,
                                                  route_map_object_t type,
                                                  void *object)
 {
@@ -206,7 +207,7 @@ static struct route_map_rule_cmd route_match_ip_next_hop_cmd = {
 /* `match ip next-hop prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
                                    route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -251,7 +252,7 @@ static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = {
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t route_match_ip_address(void *rule,
-                                                struct prefix *prefix,
+                                                const struct prefix *prefix,
                                                 route_map_object_t type,
                                                 void *object)
 {
@@ -290,7 +291,7 @@ static struct route_map_rule_cmd route_match_ip_address_cmd = {
 /* `match ip address prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
                                   route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -324,7 +325,7 @@ static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
 
 /* `match tag TAG' */
 /* Match function return 1 if match is success else return zero. */
-static route_map_result_t route_match_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_tag(void *rule, const struct prefix *p,
                                          route_map_object_t type, void *object)
 {
        route_tag_t *tag;
@@ -354,7 +355,8 @@ static struct route_map_rule_cmd route_match_tag_cmd = {
 /* `set metric METRIC' */
 
 /* Set metric to attribute. */
-static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_metric(void *rule,
+                                          const struct prefix *prefix,
                                           route_map_object_t type,
                                           void *object)
 {
@@ -453,7 +455,7 @@ static struct route_map_rule_cmd route_set_metric_cmd = {
 
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 static route_map_result_t route_set_ip_nexthop(void *rule,
-                                              struct prefix *prefix,
+                                              const struct prefix *prefix,
                                               route_map_object_t type,
                                               void *object)
 {
@@ -505,7 +507,7 @@ static struct route_map_rule_cmd route_set_ip_nexthop_cmd = {
 /* `set tag TAG' */
 
 /* Set tag to object.  ojbect must be pointer to struct attr. */
-static route_map_result_t route_set_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_tag(void *rule, const struct prefix *prefix,
                                        route_map_object_t type, void *object)
 {
        route_tag_t *tag;
index e9a38d137b40ec5392fb76f13e6ff76e9275d293..a18332516e4bd71f41f0f9bcc4872e736ceefac4 100644 (file)
@@ -38,7 +38,8 @@ struct rip_metric_modifier {
 
 /* `match metric METRIC' */
 /* Match function return 1 if match is success else return zero. */
-static route_map_result_t route_match_metric(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_metric(void *rule,
+                                            const struct prefix *prefix,
                                             route_map_object_t type,
                                             void *object)
 {
@@ -86,7 +87,7 @@ static struct route_map_rule_cmd route_match_metric_cmd = {
 /* `match interface IFNAME' */
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t route_match_interface(void *rule,
-                                               struct prefix *prefix,
+                                               const struct prefix *prefix,
                                                route_map_object_t type,
                                                void *object)
 {
@@ -128,7 +129,8 @@ static struct route_map_rule_cmd route_match_interface_cmd = {
 
 /* `match tag TAG' */
 /* Match function return 1 if match is success else return zero. */
-static route_map_result_t route_match_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_tag(void *rule,
+                                         const struct prefix *prefix,
                                          route_map_object_t type, void *object)
 {
        route_tag_t *tag;
@@ -157,7 +159,8 @@ static struct route_map_rule_cmd route_match_tag_cmd = {
 /* `set metric METRIC' */
 
 /* Set metric to attribute. */
-static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_metric(void *rule,
+                                          const struct prefix *prefix,
                                           route_map_object_t type,
                                           void *object)
 {
@@ -254,7 +257,7 @@ static struct route_map_rule_cmd route_set_metric_cmd = {
 
 /* Set nexthop to object.  ojbect must be pointer to struct attr. */
 static route_map_result_t route_set_ipv6_nexthop_local(void *rule,
-                                                      struct prefix *prefix,
+                                                      const struct prefix *p,
                                                       route_map_object_t type,
                                                       void *object)
 {
@@ -307,7 +310,8 @@ static struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd = {
 /* `set tag TAG' */
 
 /* Set tag to object.  ojbect must be pointer to struct attr. */
-static route_map_result_t route_set_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_tag(void *rule,
+                                       const struct prefix *prefix,
                                        route_map_object_t type, void *object)
 {
        route_tag_t *tag;
index 01ce7480d751ac48a09aac9813b7869b1d6aa91f..a0382827b97c331644c0d0195ccdb6b8ef320b51 100644 (file)
@@ -116,8 +116,8 @@ static void check_lookup_result(struct list *list, va_list arglist)
        assert(prefix_count == listcount(list));
 }
 
-static void do_test(struct bgp_table *table, const char *prefix, uint8_t maxlen,
-                   ...)
+static void do_test(struct bgp_table *table, const char *prefix,
+                   uint32_t maxlen, ...)
 {
        va_list arglist;
        struct list *list = list_new();
index c75a699a165fe5719497707303a37d0afea4eaa4..4612bdc26b0adc737e792c74c2255639153433a0 100644 (file)
@@ -821,6 +821,7 @@ static void parse_test(struct peer *peer, struct test_segment *t, int type)
        switch (type) {
        case CAPABILITY:
                len += 2; /* to cover the OPT-Param header */
+               __attribute__ ((fallthrough));
        case OPT_PARAM:
                printf("len: %u\n", len);
                /* peek_for_as4 wants getp at capibility*/
index 0e473d7a6b4d86f7e021b0b763139761b3bcaa4e..fe528203aa93c311afd42ac317176a05dcb1a672 100644 (file)
@@ -16,43 +16,42 @@ static size_t vertex_count;
 
 static void setup_test_vertices(void)
 {
-       struct prefix p = {
-               .family = AF_UNSPEC
+       union isis_N nid, nip = {
+               .prefix.family = AF_UNSPEC
        };
-       uint8_t node_id[7];
 
        vertices = XMALLOC(MTYPE_TMP, sizeof(*vertices) * 16);
 
-       p.family = AF_INET;
-       p.prefixlen = 24;
-       inet_pton(AF_INET, "192.168.1.0", &p.u.prefix4);
-       vertices[vertex_count] = isis_vertex_new(&p, VTYPE_IPREACH_TE);
+       nip.prefix.family = AF_INET;
+       nip.prefix.prefixlen = 24;
+       inet_pton(AF_INET, "192.168.1.0", &nip.prefix.u.prefix4);
+       vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE);
        vertices[vertex_count]->d_N = 20;
        vertex_count++;
 
-       p.family = AF_INET;
-       p.prefixlen = 24;
-       inet_pton(AF_INET, "192.168.2.0", &p.u.prefix4);
-       vertices[vertex_count] = isis_vertex_new(&p, VTYPE_IPREACH_TE);
+       nip.prefix.family = AF_INET;
+       nip.prefix.prefixlen = 24;
+       inet_pton(AF_INET, "192.168.2.0", &nip.prefix.u.prefix4);
+       vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE);
        vertices[vertex_count]->d_N = 20;
        vertex_count++;
 
-       memset(node_id, 0, sizeof(node_id));
-       node_id[6] = 1;
-       vertices[vertex_count] = isis_vertex_new(node_id, VTYPE_PSEUDO_TE_IS);
+       memset(nid.id, 0, sizeof(nid.id));
+       nid.id[6] = 1;
+       vertices[vertex_count] = isis_vertex_new(&nid, VTYPE_PSEUDO_TE_IS);
        vertices[vertex_count]->d_N = 15;
        vertex_count++;
 
-       memset(node_id, 0, sizeof(node_id));
-       node_id[5] = 2;
-       vertices[vertex_count] = isis_vertex_new(node_id, VTYPE_NONPSEUDO_TE_IS);
+       memset(nid.id, 0, sizeof(nid.id));
+       nid.id[5] = 2;
+       vertices[vertex_count] = isis_vertex_new(&nid, VTYPE_NONPSEUDO_TE_IS);
        vertices[vertex_count]->d_N = 15;
        vertex_count++;
 
-       p.family = AF_INET;
-       p.prefixlen = 24;
-       inet_pton(AF_INET, "192.168.3.0", &p.u.prefix4);
-       vertices[vertex_count] = isis_vertex_new(&p, VTYPE_IPREACH_TE);
+       nip.prefix.family = AF_INET;
+       nip.prefix.prefixlen = 24;
+       inet_pton(AF_INET, "192.168.3.0", &nip.prefix.u.prefix4);
+       vertices[vertex_count] = isis_vertex_new(&nip, VTYPE_IPREACH_TE);
        vertices[vertex_count]->d_N = 20;
        vertex_count++;
 };
@@ -76,23 +75,23 @@ static void test_ordered(void)
        assert(isis_vertex_queue_count(&q) == vertex_count);
 
        for (size_t i = 0; i < vertex_count; i++) {
-               assert(isis_find_vertex(&q, vertices[i]->N.id, vertices[i]->type) == vertices[i]);
+               assert(isis_find_vertex(&q, &vertices[i]->N, vertices[i]->type) == vertices[i]);
        }
 
        assert(isis_vertex_queue_pop(&q) == vertices[2]);
-       assert(isis_find_vertex(&q, vertices[2]->N.id, vertices[2]->type) == NULL);
+       assert(isis_find_vertex(&q, &vertices[2]->N, vertices[2]->type) == NULL);
 
        assert(isis_vertex_queue_pop(&q) == vertices[3]);
-       assert(isis_find_vertex(&q, vertices[3]->N.id, vertices[3]->type) == NULL);
+       assert(isis_find_vertex(&q, &vertices[3]->N, vertices[3]->type) == NULL);
 
        assert(isis_vertex_queue_pop(&q) == vertices[0]);
-       assert(isis_find_vertex(&q, vertices[0]->N.id, vertices[0]->type) == NULL);
+       assert(isis_find_vertex(&q, &vertices[0]->N, vertices[0]->type) == NULL);
 
        assert(isis_vertex_queue_pop(&q) == vertices[1]);
-       assert(isis_find_vertex(&q, vertices[1]->N.id, vertices[1]->type) == NULL);
+       assert(isis_find_vertex(&q, &vertices[1]->N, vertices[1]->type) == NULL);
 
        isis_vertex_queue_delete(&q, vertices[4]);
-       assert(isis_find_vertex(&q, vertices[4]->N.id, vertices[4]->type) == NULL);
+       assert(isis_find_vertex(&q, &vertices[4]->N, vertices[4]->type) == NULL);
 
        assert(isis_vertex_queue_count(&q) == 0);
        assert(isis_vertex_queue_pop(&q) == NULL);
index 53180564bd950364cb84149a2e834aec32d52da0..e717da15b34c44f69690267573905631ebcf8385 100644 (file)
@@ -392,7 +392,8 @@ static void test_state_del_one_route(struct test_state *test, struct prng *prng)
        }
 
        assert(rn);
-       srcdest_rnode_prefixes(rn, &dst_p, &src_p);
+       srcdest_rnode_prefixes(rn, (const struct prefix **)&dst_p,
+                              (const struct prefix **)&src_p);
        memcpy(&dst6_p, dst_p, sizeof(dst6_p));
        if (src_p)
                memcpy(&src6_p, src_p, sizeof(src6_p));
index 208fb116e689aced77130b37b4d1e4b5eba6248f..a9f183ed7ba85f2ffd4ecd4b5c14841c2581f407 100755 (executable)
@@ -403,7 +403,7 @@ end
                 self.save_contexts(ctx_keys, current_context_lines)
                 new_ctx = True
 
-            elif line == "end":
+            elif line in ["end", "exit-vrf"]:
                 self.save_contexts(ctx_keys, current_context_lines)
                 log.debug('LINE %-50s: exiting old context, %-50s', line, ctx_keys)
 
index 5c84219418422842abf7cad504a8da98aa8408dd..8943b434d79af3dcff3e44903539389595deb587 100644 (file)
@@ -891,8 +891,12 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        zns = zebra_ns_lookup(ns_id);
        ifa = NLMSG_DATA(h);
 
-       if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6)
+       if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6) {
+               zlog_warn(
+                       "Invalid address family: %d received from kernel interface addr change: %d",
+                       ifa->ifa_family, h->nlmsg_type);
                return 0;
+       }
 
        if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
                return 0;
@@ -986,7 +990,7 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        if (tb[IFA_LABEL])
                label = (char *)RTA_DATA(tb[IFA_LABEL]);
 
-       if (ifp && label && strcmp(ifp->name, label) == 0)
+       if (label && strcmp(ifp->name, label) == 0)
                label = NULL;
 
        /* Register interface address to the interface. */
@@ -1114,6 +1118,14 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                return 0;
        }
 
+       if (!(ifi->ifi_family == AF_UNSPEC || ifi->ifi_family == AF_BRIDGE
+             || ifi->ifi_family == AF_INET6)) {
+               zlog_warn(
+                       "Invalid address family: %d received from kernel link change: %d",
+                       ifi->ifi_family, h->nlmsg_type);
+               return 0;
+       }
+
        len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
        if (len < 0) {
                zlog_err("%s: Message received from netlink is of a broken size %d %zu",
@@ -1218,6 +1230,12 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                        /* Update interface information. */
                        set_ifindex(ifp, ifi->ifi_index, zns);
                        ifp->flags = ifi->ifi_flags & 0x0000fffff;
+                       if (!tb[IFLA_MTU]) {
+                               zlog_warn(
+                                       "RTM_NEWLINK for interface %s(%u) without MTU set",
+                                       name, ifi->ifi_index);
+                               return 0;
+                       }
                        ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]);
                        ifp->metric = 0;
                        ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
@@ -1267,6 +1285,12 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                                        bridge_ifindex, ifi->ifi_flags);
 
                        set_ifindex(ifp, ifi->ifi_index, zns);
+                       if (!tb[IFLA_MTU]) {
+                               zlog_warn(
+                                       "RTM_NEWLINK for interface %s(%u) without MTU set",
+                                       name, ifi->ifi_index);
+                               return 0;
+                       }
                        ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]);
                        ifp->metric = 0;
 
index c5246999fa47ebe5dcd457f44b724716259e7459..3e44a4170759cf0a4e5e8a6938ae97c589c9336a 100644 (file)
@@ -236,15 +236,15 @@ int main(int argc, char **argv)
                "  -z, --socket          Set path of zebra socket\n"
                "  -e, --ecmp            Specify ECMP to use.\n"
                "  -l, --label_socket    Socket to external label manager\n"
-               "  -k, --keep_kernel     Don't delete old routes which installed by zebra.\n"
+               "  -k, --keep_kernel     Don't delete old routes which were installed by zebra.\n"
                "  -r, --retain          When program terminates, retain added route by zebra.\n"
 #ifdef HAVE_NETLINK
-               "  -n, --vrfwnetns       Set VRF with NetNS\n"
+               "  -n, --vrfwnetns       Use NetNS as VRF backend\n"
                "  -s, --nl-bufsize      Set netlink receive buffer size\n"
                "      --v6-rr-semantics Use v6 RR semantics\n"
 #endif /* HAVE_NETLINK */
 #if defined(HANDLE_ZAPI_FUZZING)
-               "  -c <file>             Bypass normal startup use this file for tetsting of zapi"
+               "  -c <file>             Bypass normal startup and use this file for testing of zapi"
 #endif
        );
 
@@ -349,13 +349,6 @@ int main(int argc, char **argv)
 /* For debug purpose. */
 /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
 
-#if defined(HANDLE_ZAPI_FUZZING)
-       if (fuzzing) {
-               zserv_read_file(fuzzing);
-               exit(0);
-       }
-#endif
-
        /* Process the configuration file. Among other configuration
        *  directives we can meet those installing static routes. Such
        *  requests will not be executed immediately, but queued in
@@ -391,6 +384,14 @@ int main(int argc, char **argv)
        /* RNH init */
        zebra_rnh_init();
 
+#if defined(HANDLE_ZAPI_FUZZING)
+       if (fuzzing) {
+               zserv_read_file(fuzzing);
+               exit(0);
+       }
+#endif
+
+
        frr_run(zebrad.master);
 
        /* Not reached... */
index 57e62e4f6ee5cc9963ce6ab5ee8e719bc5abb6b2..e40bae3a3e475f37a271d21f988ae2106a938984 100644 (file)
@@ -122,7 +122,7 @@ extern int kernel_del_mac(struct interface *ifp, vlanid_t vid,
                          int local);
 
 extern int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
-                           struct ethaddr *mac);
+                           struct ethaddr *mac, uint8_t flags);
 extern int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip);
 
 /*
index 485abc3f1230331d214f325be3922f6af3a0fb3d..80841b6ac1d6d352904718302c6075b9eb60d38c 100644 (file)
@@ -387,8 +387,15 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                memcpy(&p.u.prefix4, dest, 4);
                p.prefixlen = rtm->rtm_dst_len;
 
-               src_p.prefixlen =
-                       0; // Forces debug below to not display anything
+               if (rtm->rtm_src_len != 0) {
+                       char buf[PREFIX_STRLEN];
+                       zlog_warn("unsupported IPv4 sourcedest route (dest %s vrf %u)",
+                                 prefix2str(&p, buf, sizeof(buf)), vrf_id);
+                       return 0;
+               }
+
+               /* Force debug below to not display anything for source */
+               src_p.prefixlen = 0;
        } else if (rtm->rtm_family == AF_INET6) {
                p.family = AF_INET6;
                memcpy(&p.u.prefix6, dest, 16);
@@ -399,14 +406,6 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                src_p.prefixlen = rtm->rtm_src_len;
        }
 
-       if (rtm->rtm_src_len != 0) {
-               char buf[PREFIX_STRLEN];
-               zlog_warn(
-                       "unsupported IPv[4|6] sourcedest route (dest %s vrf %u)",
-                       prefix2str(&p, buf, sizeof(buf)), vrf_id);
-               return 0;
-       }
-
        /*
         * For ZEBRA_ROUTE_KERNEL types:
         *
@@ -492,7 +491,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                        nh.vrf_id = nh_vrf_id;
 
                        rib_add(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p,
-                               NULL, &nh, table, metric, mtu, distance, tag);
+                               &src_p, &nh, table, metric, mtu, distance, tag);
                } else {
                        /* This is a multipath route */
 
@@ -581,6 +580,9 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                                        route_entry_nexthop_ifindex_add(
                                                re, index, nh_vrf_id);
 
+                               if (rtnh->rtnh_len == 0)
+                                       break;
+
                                len -= NLMSG_ALIGN(rtnh->rtnh_len);
                                rtnh = RTNH_NEXT(rtnh);
                        }
@@ -591,8 +593,8 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                        if (re->nexthop_num == 0)
                                XFREE(MTYPE_RE, re);
                        else
-                               rib_add_multipath(afi, SAFI_UNICAST, &p, NULL,
-                                                 re);
+                               rib_add_multipath(afi, SAFI_UNICAST, &p,
+                                                 &src_p, re);
                }
        } else {
                if (!tb[RTA_MULTIPATH]) {
@@ -624,12 +626,12 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                        if (gate)
                                memcpy(&nh.gate, gate, sz);
                        rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
-                                  &p, NULL, &nh, table, metric, true);
+                                  &p, &src_p, &nh, table, metric, true);
                } else {
                        /* XXX: need to compare the entire list of nexthops
                         * here for NLM_F_APPEND stupidity */
                        rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
-                                  &p, NULL, NULL, table, metric, true);
+                                  &p, &src_p, NULL, table, metric, true);
                }
        }
 
@@ -701,6 +703,9 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h,
                        oif[oif_count] = rtnh->rtnh_ifindex;
                        oif_count++;
 
+                       if (rtnh->rtnh_len == 0)
+                               break;
+
                        len -= NLMSG_ALIGN(rtnh->rtnh_len);
                        rtnh = RTNH_NEXT(rtnh);
                }
@@ -740,6 +745,15 @@ int netlink_route_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                return 0;
        }
 
+       if (!(rtm->rtm_family == AF_INET || rtm->rtm_family == AF_INET6
+             || rtm->rtm_family == AF_ETHERNET
+             || rtm->rtm_family == AF_MPLS)) {
+               zlog_warn(
+                       "Invalid address family: %d received from kernel route change: %d",
+                       rtm->rtm_family, h->nlmsg_type);
+               return 0;
+       }
+
        /* Connected route. */
        if (IS_ZEBRA_DEBUG_KERNEL)
                zlog_debug("%s %s %s proto %s NS %u",
@@ -2151,6 +2165,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
        char buf2[INET6_ADDRSTRLEN];
        int mac_present = 0;
        uint8_t ext_learned;
+       uint8_t router_flag;
 
        ndm = NLMSG_DATA(h);
 
@@ -2241,6 +2256,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
                }
 
                ext_learned = (ndm->ndm_flags & NTF_EXT_LEARNED) ? 1 : 0;
+               router_flag = (ndm->ndm_flags & NTF_ROUTER) ? 1 : 0;
 
                if (IS_ZEBRA_DEBUG_KERNEL)
                        zlog_debug(
@@ -2263,7 +2279,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
                if (ndm->ndm_state & NUD_VALID)
                        return zebra_vxlan_handle_kernel_neigh_update(
                                ifp, link_if, &ip, &mac, ndm->ndm_state,
-                               ext_learned);
+                               ext_learned, router_flag);
 
                return zebra_vxlan_handle_kernel_neigh_del(ifp, link_if, &ip);
        }
@@ -2386,12 +2402,19 @@ int netlink_neigh_change(struct nlmsghdr *h, ns_id_t ns_id)
 
        if (ndm->ndm_family == AF_INET || ndm->ndm_family == AF_INET6)
                return netlink_ipneigh_change(h, len, ns_id);
+       else {
+               zlog_warn(
+                       "Invalid address family: %d received from kernel neighbor change: %d",
+                       ndm->ndm_family, h->nlmsg_type);
+               return 0;
+       }
 
        return 0;
 }
 
 static int netlink_neigh_update2(struct interface *ifp, struct ipaddr *ip,
-                                struct ethaddr *mac, uint32_t flags, int cmd)
+                                struct ethaddr *mac, uint8_t flags,
+                                uint16_t state, int cmd)
 {
        struct {
                struct nlmsghdr n;
@@ -2414,11 +2437,10 @@ static int netlink_neigh_update2(struct interface *ifp, struct ipaddr *ip,
                req.n.nlmsg_flags |= (NLM_F_CREATE | NLM_F_REPLACE);
        req.n.nlmsg_type = cmd; // RTM_NEWNEIGH or RTM_DELNEIGH
        req.ndm.ndm_family = IS_IPADDR_V4(ip) ? AF_INET : AF_INET6;
-       req.ndm.ndm_state = flags;
+       req.ndm.ndm_state = state;
        req.ndm.ndm_ifindex = ifp->ifindex;
        req.ndm.ndm_type = RTN_UNICAST;
-       req.ndm.ndm_flags = NTF_EXT_LEARNED;
-
+       req.ndm.ndm_flags = flags;
 
        ipa_len = IS_IPADDR_V4(ip) ? IPV4_MAX_BYTELEN : IPV6_MAX_BYTELEN;
        addattr_l(&req.n, sizeof(req), NDA_DST, &ip->ip.addr, ipa_len);
@@ -2426,12 +2448,12 @@ static int netlink_neigh_update2(struct interface *ifp, struct ipaddr *ip,
                addattr_l(&req.n, sizeof(req), NDA_LLADDR, mac, 6);
 
        if (IS_ZEBRA_DEBUG_KERNEL)
-               zlog_debug("Tx %s family %s IF %s(%u) Neigh %s MAC %s",
+               zlog_debug("Tx %s family %s IF %s(%u) Neigh %s MAC %s flags 0x%x",
                           nl_msg_type_to_str(cmd),
                           nl_family_to_str(req.ndm.ndm_family), ifp->name,
                           ifp->ifindex, ipaddr2str(ip, buf, sizeof(buf)),
                           mac ? prefix_mac2str(mac, buf2, sizeof(buf2))
-                              : "null");
+                              : "null", flags);
 
        return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
                            0);
@@ -2452,14 +2474,15 @@ int kernel_del_mac(struct interface *ifp, vlanid_t vid, struct ethaddr *mac,
 }
 
 int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
-                    struct ethaddr *mac)
+                    struct ethaddr *mac, uint8_t flags)
 {
-       return netlink_neigh_update2(ifp, ip, mac, NUD_NOARP, RTM_NEWNEIGH);
+       return netlink_neigh_update2(ifp, ip, mac, flags,
+                                    NUD_NOARP, RTM_NEWNEIGH);
 }
 
 int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip)
 {
-       return netlink_neigh_update2(ifp, ip, NULL, 0, RTM_DELNEIGH);
+       return netlink_neigh_update2(ifp, ip, NULL, 0, 0, RTM_DELNEIGH);
 }
 
 /*
index cba0376300abe962f47d5fa70108e9e150698bcf..346699198f9b8c15f22f724da4fdeead4fec6e22 100644 (file)
@@ -88,7 +88,8 @@ static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label,
 #endif
 
 /* Interface between zebra message and rtm message. */
-static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
+static int kernel_rtm_ipv4(int cmd, const struct prefix *p,
+                          struct route_entry *re)
 
 {
        struct sockaddr_in *mask = NULL;
@@ -272,7 +273,8 @@ static int sin6_masklen(struct in6_addr mask)
 #endif /* SIN6_LEN */
 
 /* Interface between zebra message and rtm message. */
-static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
+static int kernel_rtm_ipv6(int cmd, const struct prefix *p,
+                          struct route_entry *re)
 {
        struct sockaddr_in6 *mask;
        struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
@@ -374,7 +376,7 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
        return 0; /*XXX*/
 }
 
-static int kernel_rtm(int cmd, struct prefix *p, struct route_entry *re)
+static int kernel_rtm(int cmd, const struct prefix *p, struct route_entry *re)
 {
        switch (PREFIX_FAMILY(p)) {
        case AF_INET:
@@ -460,7 +462,7 @@ int kernel_del_mac(struct interface *ifp, vlanid_t vid, struct ethaddr *mac,
 }
 
 int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip,
-                    struct ethaddr *mac)
+                    struct ethaddr *mac, uint8_t flags)
 {
        return 0;
 }
index c7a8517e17c73c0ea496db700a5df9db85d24960..d683e92bcc7dc3d69c0d4796a777da59d671e982 100644 (file)
@@ -204,8 +204,12 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        }
 
        frh = NLMSG_DATA(h);
-       if (frh->family != AF_INET && frh->family != AF_INET6)
+       if (frh->family != AF_INET && frh->family != AF_INET6) {
+               zlog_warn(
+                       "Invalid address family: %d received from kernel rule change: %d",
+                       frh->family, h->nlmsg_type);
                return 0;
+       }
        if (frh->action != FR_ACT_TO_TBL)
                return 0;
 
index d0ea661403d0bdc0ffecce3289ec8a4d3ac540ae..2dd686fd0dbe2bdb3f96d44f82f6b2ed6f4f97a8 100644 (file)
@@ -80,6 +80,8 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name)
        ns_id = zebra_ns_id_get(netnspath);
        if (zserv_privs.change(ZPRIVS_LOWER))
                zlog_err("Can't lower privileges");
+       if (ns_id == NS_UNKNOWN)
+               return;
        ns_id_external = ns_map_nsid_with_external(ns_id, true);
        /* if VRF with NS ID already present */
        vrf = vrf_lookup_by_id((vrf_id_t)ns_id_external);
@@ -103,6 +105,7 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name)
        if (ret != CMD_SUCCESS) {
                zlog_warn("NS notify : failed to create NS %s", netnspath);
                ns_map_nsid_with_external(ns_id, false);
+               vrf_delete(vrf);
                return;
        }
        zlog_info("NS notify : created VRF %s NS %s", name, netnspath);
index 8c23bf34cf1670c080003fafe9dc4ece86d73fb9..5975c4058b99b2454b5b624fbb1486f211de5edf 100644 (file)
@@ -615,7 +615,7 @@ static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt)
 
 int zebra_ptm_sock_read(struct thread *thread)
 {
-       int sock, done = 0;
+       int sock;
        int rc;
 
        errno = 0;
@@ -625,28 +625,24 @@ int zebra_ptm_sock_read(struct thread *thread)
                return -1;
 
        /* PTM communicates in CSV format */
-       while (!done) {
+       do {
                rc = ptm_lib_process_msg(ptm_hdl, sock, ptm_cb.in_data,
                                         ZEBRA_PTM_MAX_SOCKBUF, NULL);
-               if (rc <= 0)
-                       break;
-       }
+       } while (rc > 0);
 
-       if (rc <= 0) {
-               if (((rc == 0) && !errno)
-                   || (errno && (errno != EWOULDBLOCK) && (errno != EAGAIN))) {
-                       zlog_warn("%s routing socket error: %s(%d) bytes %d",
-                                 __func__, safe_strerror(errno), errno, rc);
-
-                       close(ptm_cb.ptm_sock);
-                       ptm_cb.ptm_sock = -1;
-                       zebra_ptm_reset_status(0);
-                       ptm_cb.t_timer = NULL;
-                       thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
-                                        ptm_cb.reconnect_time,
-                                        &ptm_cb.t_timer);
-                       return (-1);
-               }
+       if (((rc == 0) && !errno)
+           || (errno && (errno != EWOULDBLOCK) && (errno != EAGAIN))) {
+               zlog_warn("%s routing socket error: %s(%d) bytes %d",
+                         __func__, safe_strerror(errno), errno, rc);
+
+               close(ptm_cb.ptm_sock);
+               ptm_cb.ptm_sock = -1;
+               zebra_ptm_reset_status(0);
+               ptm_cb.t_timer = NULL;
+               thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
+                                ptm_cb.reconnect_time,
+                                &ptm_cb.t_timer);
+               return (-1);
        }
 
        ptm_cb.t_read = NULL;
index 9bf6bfa22f08d949d19879a43408b744315e49f4..71d48632c14a434ec50c4f5abe61a8f42b7f40ec 100644 (file)
@@ -2331,7 +2331,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
        if (!re)
                return 0;
 
-       assert(!src_p || afi == AFI_IP6);
+       assert(!src_p || !src_p->prefixlen || afi == AFI_IP6);
 
        /* Lookup table.  */
        table = zebra_vrf_table_with_table_id(afi, safi, re->vrf_id, re->table);
@@ -2421,7 +2421,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
        char buf2[INET6_ADDRSTRLEN];
        rib_dest_t *dest;
 
-       assert(!src_p || afi == AFI_IP6);
+       assert(!src_p || !src_p->prefixlen || afi == AFI_IP6);
 
        /* Lookup table.  */
        table = zebra_vrf_table_with_table_id(afi, safi, vrf_id, table_id);
index bf6718164f087d9b7d6217f632dc6fae5fe91d82..0b48e87b1b7a173aca12301bc32f57a9a6e0b40f 100644 (file)
@@ -137,7 +137,8 @@ static int zebra_route_match_delete(struct vty *vty, const char *command,
 /* 'match tag TAG'
  * Match function return 1 if match is success else return 0
  */
-static route_map_result_t route_match_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_tag(void *rule,
+                                         const struct prefix *prefix,
                                          route_map_object_t type, void *object)
 {
        route_tag_t *tag;
@@ -163,7 +164,7 @@ static struct route_map_rule_cmd route_match_tag_cmd = {
 /* `match interface IFNAME' */
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t route_match_interface(void *rule,
-                                               struct prefix *prefix,
+                                               const struct prefix *prefix,
                                                route_map_object_t type,
                                                void *object)
 {
@@ -879,7 +880,7 @@ DEFUN (show_ipv6_protocol_nht,
 
 /* Match function return 1 if match is success else return zero. */
 static route_map_result_t route_match_ip_next_hop(void *rule,
-                                                 struct prefix *prefix,
+                                                 const struct prefix *prefix,
                                                  route_map_object_t type,
                                                  void *object)
 {
@@ -937,7 +938,7 @@ static struct route_map_rule_cmd route_match_ip_next_hop_cmd = {
 /* `match ip next-hop prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
                                    route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -993,7 +994,7 @@ static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = {
 /* Match function should return 1 if match is success else return
    zero. */
 static route_map_result_t route_match_ip_address(void *rule,
-                                                struct prefix *prefix,
+                                                const struct prefix *prefix,
                                                 route_map_object_t type,
                                                 void *object)
 {
@@ -1032,7 +1033,7 @@ static struct route_map_rule_cmd route_match_ip_address_cmd = {
 /* `match ip address prefix-list PREFIX_LIST' */
 
 static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
                                   route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
@@ -1068,7 +1069,7 @@ static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
 /* `match ip address prefix-len PREFIXLEN' */
 
 static route_map_result_t
-route_match_address_prefix_len(void *rule, struct prefix *prefix,
+route_match_address_prefix_len(void *rule, const struct prefix *prefix,
                               route_map_object_t type, void *object)
 {
        uint32_t *prefixlen = (uint32_t *)rule;
@@ -1122,7 +1123,7 @@ static struct route_map_rule_cmd route_match_ipv6_address_prefix_len_cmd = {
 /* `match ip nexthop prefix-len PREFIXLEN' */
 
 static route_map_result_t
-route_match_ip_nexthop_prefix_len(void *rule, struct prefix *prefix,
+route_match_ip_nexthop_prefix_len(void *rule, const struct prefix *prefix,
                                  route_map_object_t type, void *object)
 {
        uint32_t *prefixlen = (uint32_t *)rule;
@@ -1162,7 +1163,7 @@ static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd = {
 /* `match source-protocol PROTOCOL' */
 
 static route_map_result_t route_match_source_protocol(void *rule,
-                                                     struct prefix *prefix,
+                                                     const struct prefix *p,
                                                      route_map_object_t type,
                                                      void *object)
 {
@@ -1204,7 +1205,7 @@ static struct route_map_rule_cmd route_match_source_protocol_cmd = {
 
 /* `source-instance` */
 static route_map_result_t route_match_source_instance(void *rule,
-                                                     struct prefix *prefix,
+                                                     const struct prefix *p,
                                                      route_map_object_t type,
                                                      void *object)
 {
@@ -1246,7 +1247,7 @@ static struct route_map_rule_cmd route_match_source_instance_cmd = {
 /* `set src A.B.C.D' */
 
 /* Set src. */
-static route_map_result_t route_set_src(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_src(void *rule, const struct prefix *prefix,
                                        route_map_object_t type, void *object)
 {
        struct nh_rmap_obj *nh_data;
@@ -1359,8 +1360,7 @@ route_map_result_t zebra_route_map_check(int family, int rib_type,
                rmap = route_map_lookup_by_name(
                        proto_rm[family][ZEBRA_ROUTE_MAX]);
        if (rmap) {
-               ret = route_map_apply(rmap, (struct prefix *)p,
-                                     RMAP_ZEBRA, &nh_obj);
+               ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
        }
 
        return (ret);
@@ -1385,7 +1385,8 @@ void zebra_del_import_table_route_map(afi_t afi, uint32_t table)
 
 route_map_result_t
 zebra_import_table_route_map_check(int family, int re_type, uint8_t instance,
-                                  struct prefix *p, struct nexthop *nexthop,
+                                  const struct prefix *p,
+                                  struct nexthop *nexthop,
                                   vrf_id_t vrf_id, route_tag_t tag,
                                   const char *rmap_name)
 {
@@ -1410,7 +1411,7 @@ zebra_import_table_route_map_check(int family, int re_type, uint8_t instance,
 }
 
 route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
-                                            struct prefix *p,
+                                            const struct prefix *p,
                                             struct route_entry *re,
                                             struct nexthop *nexthop)
 {
@@ -1430,11 +1431,10 @@ route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
        if (!rmap && nht_rm[family][ZEBRA_ROUTE_MAX])
                rmap = route_map_lookup_by_name(
                        nht_rm[family][ZEBRA_ROUTE_MAX]);
-       if (rmap) {
+       if (rmap)
                ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
-       }
 
-       return (ret);
+       return ret;
 }
 
 static void zebra_route_map_mark_update(const char *rmap_name)
index 688c8b7203d2544f94de5d95c6300e254e86f41e..d33487d7afb68b7dc20a2c9aaf92f510a70b5e4a 100644 (file)
@@ -35,7 +35,8 @@ extern void zebra_route_map_write_delay_timer(struct vty *);
 
 extern route_map_result_t
 zebra_import_table_route_map_check(int family, int rib_type, uint8_t instance,
-                                  struct prefix *p, struct nexthop *nexthop,
+                                  const struct prefix *p,
+                                  struct nexthop *nexthop,
                                   vrf_id_t vrf_id, route_tag_t tag,
                                   const char *rmap_name);
 extern route_map_result_t
@@ -43,7 +44,7 @@ zebra_route_map_check(int family, int rib_type, uint8_t instance,
                      const struct prefix *p, struct nexthop *nexthop,
                      vrf_id_t vrf_id, route_tag_t tag);
 extern route_map_result_t
-zebra_nht_route_map_check(int family, int client_proto, struct prefix *p,
+zebra_nht_route_map_check(int family, int client_proto, const struct prefix *p,
                          struct route_entry *, struct nexthop *nexthop);
 
 
index 55c4f6e916b1106a6cfe10969e9bc56d748590fc..8ee47d2f1b6508c6864eebedb3802dbf8508b2d7 100644 (file)
@@ -1198,7 +1198,8 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
                                break;
                        }
 
-                       if (re->vrf_id != nexthop->vrf_id) {
+                       if ((re->vrf_id != nexthop->vrf_id)
+                            && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
                                struct vrf *vrf =
                                        vrf_lookup_by_id(nexthop->vrf_id);
 
@@ -1415,7 +1416,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
                                break;
                        }
 
-                       if (nexthop->vrf_id != re->vrf_id) {
+                       if ((nexthop->vrf_id != re->vrf_id)
+                            && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
                                struct vrf *vrf =
                                        vrf_lookup_by_id(nexthop->vrf_id);
 
@@ -1569,7 +1571,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
                        break;
                }
 
-               if (nexthop->vrf_id != re->vrf_id) {
+               if ((nexthop->vrf_id != re->vrf_id)
+                    && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
                        struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
 
                        if (vrf)
@@ -1651,7 +1654,7 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
                json = json_object_new_object();
 
        /* Show all routes. */
-       for (rn = route_top(table); rn; rn = route_next(rn)) {
+       for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
                dest = rib_dest_from_rnode(rn);
 
                RNODE_FOREACH_RE (rn, re) {
index 59f0cf52f0a1b46664f472442b23090663d568c3..06d1b3618c97f3cc99159ddded5d96dc1e92132f 100644 (file)
@@ -33,6 +33,9 @@
 #include "jhash.h"
 #include "vlan.h"
 #include "vxlan.h"
+#ifdef GNU_LINUX
+#include <linux/neighbour.h>
+#endif
 
 #include "zebra/rib.h"
 #include "zebra/rt.h"
@@ -282,6 +285,7 @@ static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt)
        ipaddr2str(&n->ip, buf, sizeof(buf)), width = strlen(buf);
        if (width > wctx->addr_width)
                wctx->addr_width = width;
+
 }
 
 /*
@@ -327,6 +331,10 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
                else
                        json_object_boolean_true_add(json, "defaultGateway");
        }
+       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)) {
+               if (!json)
+                       vty_out(vty, " Router");
+       }
        if (json == NULL)
                vty_out(vty, "\n");
 }
@@ -432,11 +440,11 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
                return;
        }
        num_neigh = hashcount(zvni->neigh_table);
-       if (json == NULL)
+       if (json == NULL) {
                vty_out(vty,
                        "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
                        zvni->vni, num_neigh);
-       else {
+       else {
                json_vni = json_object_new_object();
                json_object_int_add(json_vni, "numArpNd", num_neigh);
                snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
@@ -458,9 +466,10 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
        wctx.json = json_vni;
        hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
 
-       if (json == NULL)
+       if (json == NULL) {
                vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
                        "Type", "MAC", "Remote VTEP");
+       }
        hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
 
        if (json)
@@ -581,6 +590,9 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
        if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
                vty_out(vty, " Default-gateway Mac ");
 
+       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
+               vty_out(vty, " Remote-gateway Mac ");
+
        vty_out(vty, "\n");
        /* print all the associated neigh */
        vty_out(vty, " Neighbors:\n");
@@ -1553,6 +1565,9 @@ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
 
        if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_DEF_GW))
                SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+       /* Set router flag (R-bit) based on local neigh entry add */
+       if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_ROUTER_FLAG))
+               SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
 
        return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
                                             ZEBRA_MACIP_ADD);
@@ -1576,6 +1591,8 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
        struct zebra_if *zif;
        struct zebra_l2info_vxlan *vxl;
        struct interface *vlan_if;
+       uint8_t flags;
+       int ret = 0;
 
        if (!(n->flags & ZEBRA_NEIGH_REMOTE))
                return 0;
@@ -1588,8 +1605,13 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
        vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
        if (!vlan_if)
                return -1;
-
-       return kernel_add_neigh(vlan_if, &n->ip, &n->emac);
+#ifdef GNU_LINUX
+       flags = NTF_EXT_LEARNED;
+       if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
+               flags |= NTF_ROUTER;
+       ret = kernel_add_neigh(vlan_if, &n->ip, &n->emac, flags);
+#endif
+       return ret;
 }
 
 /*
@@ -1811,6 +1833,9 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
        /* Set "local" forwarding info. */
        SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
        SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
+       /* Set Router flag (R-bit) */
+       if (ip->ipa_type == IPADDR_V6)
+               SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
        memcpy(&n->emac, macaddr, ETH_ALEN);
        n->ifindex = ifp->ifindex;
 
@@ -1820,10 +1845,10 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
 
        if (IS_ZEBRA_DEBUG_VXLAN)
                zlog_debug(
-                       "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP",
+                       "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP with flags 0x%x",
                        ifp->name, ifp->ifindex, zvni->vni,
                        prefix_mac2str(macaddr, buf, sizeof(buf)),
-                       ipaddr2str(ip, buf2, sizeof(buf2)));
+                       ipaddr2str(ip, buf2, sizeof(buf2)), n->flags);
 
        zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags);
 
@@ -1966,7 +1991,8 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
 static int zvni_local_neigh_update(zebra_vni_t *zvni,
                                   struct interface *ifp,
                                   struct ipaddr *ip,
-                                  struct ethaddr *macaddr)
+                                  struct ethaddr *macaddr,
+                                  uint8_t router_flag)
 {
        char buf[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
@@ -2084,15 +2110,19 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
                return 0;
        }
 
+       /*Set router flag (R-bit) */
+       if (router_flag)
+               SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+
        /* Inform BGP. */
        if (IS_ZEBRA_DEBUG_VXLAN)
-               zlog_debug("Neigh %s (MAC %s) is now ACTIVE on L2-VNI %u",
+               zlog_debug("Neigh %s (MAC %s) is now ACTIVE on L2-VNI %u with flags 0x%x",
                           ipaddr2str(ip, buf2, sizeof(buf2)),
                           prefix_mac2str(macaddr, buf, sizeof(buf)),
-                          zvni->vni);
+                          zvni->vni, n->flags);
        ZEBRA_NEIGH_SET_ACTIVE(n);
 
-       return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, 0);
+       return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags);
 }
 
 static int zvni_remote_neigh_update(zebra_vni_t *zvni,
@@ -2534,7 +2564,8 @@ static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
                return -1;
        vxl = &zif->l2info.vxl;
 
-       sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
+       sticky = CHECK_FLAG(mac->flags,
+                        (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW)) ? 1 : 0;
 
        return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
                              mac->fwd_info.r_vtep_ip, sticky);
@@ -3362,14 +3393,22 @@ static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
  */
 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
 {
+       uint8_t flags;
+       int ret = 0;
+
        if (!is_l3vni_oper_up(zl3vni))
                return -1;
 
        if (!(n->flags & ZEBRA_NEIGH_REMOTE)
            || !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
                return 0;
-
-       return kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac);
+#ifdef GNU_LINUX
+       flags = NTF_EXT_LEARNED;
+       if (n->flags & ZEBRA_NEIGH_ROUTER_FLAG)
+               flags |= NTF_ROUTER;
+       ret = kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac, flags);
+#endif
+       return ret;
 }
 
 /*
@@ -4513,9 +4552,11 @@ void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
        memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
        wctx.zvni = zvni;
        wctx.vty = vty;
+       wctx.addr_width = 15;
        wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
        wctx.r_vtep_ip = vtep_ip;
        wctx.json = json;
+       hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
        hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
 
        if (use_json) {
@@ -4944,7 +4985,8 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
                                           struct ipaddr *ip,
                                           struct ethaddr *macaddr,
                                           uint16_t state,
-                                          uint8_t ext_learned)
+                                          uint8_t ext_learned,
+                                          uint8_t router_flag)
 {
        char buf[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
@@ -4975,7 +5017,8 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
 
        /* Is this about a local neighbor or a remote one? */
        if (!ext_learned)
-               return zvni_local_neigh_update(zvni, ifp, ip, macaddr);
+               return zvni_local_neigh_update(zvni, ifp, ip, macaddr,
+                                              router_flag);
 
        return zvni_remote_neigh_update(zvni, ifp, ip, macaddr, state);
 }
@@ -5152,6 +5195,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
        char buf[ETHER_ADDR_STRLEN];
        char buf1[INET6_ADDRSTRLEN];
        uint8_t sticky = 0;
+       u_char remote_gw = 0;
        uint8_t flags = 0;
        struct interface *ifp = NULL;
        struct zebra_if *zif = NULL;
@@ -5193,6 +5237,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
                /* Get flags - sticky mac and/or gateway mac */
                STREAM_GETC(s, flags);
                sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
+               remote_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
                l++;
 
                if (IS_ZEBRA_DEBUG_VXLAN)
@@ -5266,6 +5311,8 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
                if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
                    || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0)
                               != sticky
+                   || (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? 1 : 0)
+                              != remote_gw
                    || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip))
                        update_mac = 1;
 
@@ -5297,6 +5344,11 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
                        else
                                UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
 
+                       if (remote_gw)
+                               SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
+                       else
+                               UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW);
+
                        zvni_process_neigh_on_remote_mac_add(zvni, mac);
 
                        /* Install the entry. */
@@ -5353,6 +5405,10 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
                        n->r_vtep_ip = vtep_ip;
                        SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
 
+                       /* Set router flag (R-bit) to this Neighbor entry */
+                       if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
+                               SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+
                        /* Install the entry. */
                        zvni_neigh_install(zvni, n);
                }
index 34d115275102ddab077e868e43cbcbd4661e69b7..2732ef72edfd9e8408af0b0b532a81388102cb43 100644 (file)
@@ -124,7 +124,8 @@ extern int zebra_vxlan_svi_down(struct interface *ifp,
                                struct interface *link_if);
 extern int zebra_vxlan_handle_kernel_neigh_update(
        struct interface *ifp, struct interface *link_if, struct ipaddr *ip,
-       struct ethaddr *macaddr, uint16_t state, uint8_t ext_learned);
+       struct ethaddr *macaddr, uint16_t state, uint8_t ext_learned,
+       uint8_t router_flag);
 extern int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
                                       struct interface *link_if,
                                       struct ipaddr *ip);
index fa7075f2de875ccaea81645178f32336e10d28a6..e86967041b2e6daeb72466182093d7c2b0e74da7 100644 (file)
@@ -247,6 +247,8 @@ struct zebra_mac_t_ {
 #define ZEBRA_MAC_STICKY  0x08  /* Static MAC */
 #define ZEBRA_MAC_REMOTE_RMAC  0x10  /* remote router mac */
 #define ZEBRA_MAC_DEF_GW  0x20
+/* remote VTEP advertised MAC as default GW */
+#define ZEBRA_MAC_REMOTE_DEF_GW        0x40
 
        /* Local or remote info. */
        union {
@@ -329,6 +331,7 @@ struct zebra_neigh_t_ {
 #define ZEBRA_NEIGH_REMOTE    0x02
 #define ZEBRA_NEIGH_REMOTE_NH    0x04 /* neigh entry for remote vtep */
 #define ZEBRA_NEIGH_DEF_GW    0x08
+#define ZEBRA_NEIGH_ROUTER_FLAG 0x10
 
        enum zebra_neigh_state state;
 
index b08da9cebd087102e5b618b48c874d3d3aed47d4..725cc9229c8e16e551b718870495742a56692841 100644 (file)
@@ -640,7 +640,7 @@ static int zserv_handle_client_close(struct thread *thread)
  * sock
  *    client's socket file descriptor
  */
-static void zserv_client_create(int sock)
+static struct zserv *zserv_client_create(int sock)
 {
        struct zserv *client;
        int i;
@@ -696,6 +696,8 @@ static void zserv_client_create(int sock)
 
        /* start pthread */
        frr_pthread_run(client->pthread, NULL);
+
+       return client;
 }
 
 /*
@@ -1022,23 +1024,12 @@ DEFUN (show_zebra_client_summary,
 void zserv_read_file(char *input)
 {
        int fd;
-       struct zserv *client = NULL;
        struct thread t;
 
-       zserv_client_create(-1);
-
-       frr_pthread_stop(client->pthread, NULL);
-       frr_pthread_destroy(client->pthread);
-       client->pthread = NULL;
-
-       t.arg = client;
-
        fd = open(input, O_RDONLY | O_NONBLOCK);
        t.u.fd = fd;
 
-       zserv_read(&t);
-
-       close(fd);
+       zserv_client_create(fd);
 }
 #endif