]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #2665 from chiragshah6/evpn_dev
authorRuss White <russ@riw.us>
Tue, 24 Jul 2018 15:55:08 +0000 (11:55 -0400)
committerGitHub <noreply@github.com>
Tue, 24 Jul 2018 15:55:08 +0000 (11:55 -0400)
bgpd: support evpn nd ext community

58 files changed:
Makefile.am
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
tools/frr-reload.py
zebra/if_netlink.c
zebra/main.c
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_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 d89716ca399a01c3cf9e5f9e84bd3b6cddcf875d..8d71c3123e830af11eb70ac8877101f08bf46b4b 100644 (file)
@@ -338,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..f63d591d6f89f86a1c54132633c48f25142593a1 100644 (file)
@@ -772,7 +772,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 +806,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 +2013,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 +9115,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 +9138,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 7c045f62f1bc897347758e3e151a32fb8a58108f..49419b3df33921eb225d375c1205789e9f520333 100644 (file)
@@ -459,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 */
@@ -600,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..78152b266f0fad8fec0e8e75c51ef737097ef32b 100644 (file)
@@ -418,12 +418,14 @@ 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;
@@ -487,16 +489,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 +559,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 +794,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 +818,63 @@ 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;
        }
 
+       /*
+        * 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 +882,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 +903,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 +915,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 +934,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 +949,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 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..2743f34cb4fd2f57934f7ac3f3c0d461c30c3b95 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",
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 7225fc80ffb7c7208a0de679eeb02c04b7d37e20..4fe42f2ebc6bc4c0fb22114c16076363bc1e35f6 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 */
 
@@ -591,8 +590,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 +623,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);
                }
        }
 
@@ -740,6 +739,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",
@@ -2388,6 +2396,12 @@ 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;
 }
index c0b815644bbbd6b62ce104dcd5ad9b4648f82abf..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:
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 71ae3ab39d6560e0bc24757e97a736cca1ec11fd..06d1b3618c97f3cc99159ddded5d96dc1e92132f 100644 (file)
@@ -590,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");
@@ -2561,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);
@@ -5191,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;
@@ -5232,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)
@@ -5305,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;
 
@@ -5336,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. */
index 57b9a279c93bf22429d9e2f886cb45354261850f..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 {
index b08da9cebd087102e5b618b48c874d3d3aed47d4..4c90757d70489e02ac6c42d0cb60fc8685c8b5f1 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;
 }
 
 /*
@@ -1025,20 +1027,10 @@ void zserv_read_file(char *input)
        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