]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #4143 from opensourcerouting/update-libyang-build-intr
authorQuentin Young <qlyoung@users.noreply.github.com>
Tue, 16 Apr 2019 15:58:51 +0000 (11:58 -0400)
committerGitHub <noreply@github.com>
Tue, 16 Apr 2019 15:58:51 +0000 (11:58 -0400)
doc: update libyang build instructions to enable compiler optimizations

22 files changed:
bgpd/bgp_evpn_vty.c
bgpd/bgp_flowspec_vty.c
bgpd/bgp_pbr.c
bgpd/bgp_route.c
bgpd/bgp_zebra.c
isisd/isis_cli.c
isisd/isis_northbound.c
isisd/isis_redist.c
lib/linklist.c
lib/linklist.h
lib/vrf.c
pimd/pim_cmd.c
pimd/pim_nht.c
pimd/pim_nht.h
pimd/pim_rp.c
pimd/pim_rpf.c
pimd/pim_upstream.c
pimd/pim_zebra.c
yang/frr-isisd.yang
zebra/zebra_dplane.c
zebra/zebra_dplane.h
zebra/zebra_rib.c

index 0454fc2212674acc844c5d6e246a0b6c173df163..5a5d1e0cd4174e950db2002521a2aa5b193776a4 100644 (file)
@@ -51,6 +51,7 @@ struct vni_walk_ctx {
        struct vty *vty;
        struct in_addr vtep_ip;
        json_object *json;
+       int detail;
 };
 
 static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt,
@@ -616,12 +617,12 @@ static void show_esi_routes(struct bgp *bgp,
 
 static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
                            struct vty *vty, struct in_addr vtep_ip,
-                           json_object *json)
+                           json_object *json, int detail)
 {
        struct bgp_node *rn;
        struct bgp_path_info *pi;
        struct bgp_table *table;
-       int header = 1;
+       int header = detail ? 0 : 1;
        uint64_t tbl_ver;
        uint32_t prefix_cnt, path_cnt;
 
@@ -675,7 +676,13 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
                        if (json)
                                json_path = json_object_new_array();
 
-                       route_vty_out(vty, &rn->p, pi, 0, SAFI_EVPN, json_path);
+                       if (detail)
+                               route_vty_out_detail(vty, bgp, &rn->p, pi,
+                                                    AFI_L2VPN, SAFI_EVPN,
+                                                    json_path);
+                       else
+                               route_vty_out(vty, &rn->p, pi, 0, SAFI_EVPN,
+                                             json_path);
 
                        if (json)
                                json_object_array_add(json_paths, json_path);
@@ -706,6 +713,7 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
                        vty_out(vty, "\nDisplayed %u prefixes (%u paths)%s\n",
                                prefix_cnt, path_cnt,
                                type ? " (of requested type)" : "");
+               vty_out(vty, "\n");
        }
 }
 
@@ -726,7 +734,8 @@ static void show_vni_routes_hash(struct hash_bucket *bucket, void *arg)
                vty_out(vty, "\nVNI: %d\n\n", vpn->vni);
        }
 
-       show_vni_routes(wctx->bgp, vpn, 0, wctx->vty, wctx->vtep_ip, json_vni);
+       show_vni_routes(wctx->bgp, vpn, 0, wctx->vty, wctx->vtep_ip, json_vni,
+                       wctx->detail);
 
        if (json)
                json_object_object_add(json, vni_str, json_vni);
@@ -1995,7 +2004,8 @@ static void evpn_show_import_rts(struct vty *vty, struct bgp *bgp,
  * Display EVPN routes for all VNIs - vty handler.
  */
 static void evpn_show_routes_vni_all(struct vty *vty, struct bgp *bgp,
-                                    struct in_addr vtep_ip, json_object *json)
+                                    struct in_addr vtep_ip, json_object *json,
+                                    int detail)
 {
        uint32_t num_vnis;
        struct vni_walk_ctx wctx;
@@ -2008,6 +2018,7 @@ static void evpn_show_routes_vni_all(struct vty *vty, struct bgp *bgp,
        wctx.vty = vty;
        wctx.vtep_ip = vtep_ip;
        wctx.json = json;
+       wctx.detail = detail;
        hash_iterate(bgp->vnihash, (void (*)(struct hash_bucket *,
                                             void *))show_vni_routes_hash,
                     &wctx);
@@ -2188,7 +2199,7 @@ static void evpn_show_routes_vni(struct vty *vty, struct bgp *bgp, vni_t vni,
        }
 
        /* Walk this VNI's route table and display appropriate routes. */
-       show_vni_routes(bgp, vpn, type, vty, vtep_ip, json);
+       show_vni_routes(bgp, vpn, type, vty, vtep_ip, json, 0);
 }
 
 /*
@@ -4075,7 +4086,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast,
  */
 DEFUN(show_bgp_l2vpn_evpn_route_vni_all,
       show_bgp_l2vpn_evpn_route_vni_all_cmd,
-      "show bgp l2vpn evpn route vni all [vtep A.B.C.D] [json]",
+      "show bgp l2vpn evpn route vni all [detail] [vtep A.B.C.D] [json]",
       SHOW_STR
       BGP_STR
       L2VPN_HELP_STR
@@ -4083,6 +4094,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_all,
       "EVPN route information\n"
       "VXLAN Network Identifier\n"
       "All VNIs\n"
+      "Print Detailed Output\n"
       "Remote VTEP\n"
       "Remote VTEP IP address\n"
       JSON_STR)
@@ -4092,6 +4104,8 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_all,
        int idx = 0;
        bool uj = false;
        json_object *json = NULL;
+       /* Detail Adjust. Adjust indexes according to detail option */
+       int da = 0;
 
        bgp = bgp_get_evpn();
        if (!bgp)
@@ -4105,16 +4119,21 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_all,
        if (!argv_find(argv, argc, "evpn", &idx))
                return CMD_WARNING;
 
+       if (argv_find(argv, argc, "detail", &da))
+               da = 1;
+
+       /* vtep-ip position depends on detail option */
        vtep_ip.s_addr = 0;
-       if ((!uj && (argc == (idx + 1 + 5) && argv[idx + 5]->arg))
-           || (uj && (argc == (idx + 1 + 6) && argv[idx + 5]->arg))) {
-               if (!inet_aton(argv[idx + 5]->arg, &vtep_ip)) {
+       if ((!uj && (argc == (idx + 1 + 5 + da) && argv[idx + 5 + da]->arg))
+           || (uj
+               && (argc == (idx + 1 + 6 + da) && argv[idx + 5 + da]->arg))) {
+               if (!inet_aton(argv[idx + 5 + da]->arg, &vtep_ip)) {
                        vty_out(vty, "%% Malformed VTEP IP address\n");
                        return CMD_WARNING;
                }
        }
 
-       evpn_show_routes_vni_all(vty, bgp, vtep_ip, json);
+       evpn_show_routes_vni_all(vty, bgp, vtep_ip, json, da);
 
        if (uj) {
                vty_out(vty, "%s\n", json_object_to_json_string_ext(
@@ -4345,11 +4364,12 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_multicast,
             "Originating Router IP address\n")
 
 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_all, show_bgp_evpn_route_vni_all_cmd,
-            "show bgp evpn route vni all [vtep A.B.C.D]",
+            "show bgp evpn route vni all [detail] [vtep A.B.C.D]",
             SHOW_STR BGP_STR EVPN_HELP_STR
             "EVPN route information\n"
             "VXLAN Network Identifier\n"
             "All VNIs\n"
+            "Print Detailed Output\n"
             "Remote VTEP\n"
             "Remote VTEP IP address\n")
 
index 72ee8bb4cee14c8b9c72506128ab752db65c2f9d..2d6523ed31ed5eb86ab1cc54e98affc21ac3225a 100644 (file)
@@ -332,14 +332,12 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
        if (display == NLRI_STRING_FORMAT_LARGE) {
                struct bgp_path_info_extra *extra =
                        bgp_path_info_extra_get(path);
+               bool list_began = false;
 
-               if (listcount(extra->bgp_fs_pbr) ||
-                   listcount(extra->bgp_fs_iprule)) {
+               if (extra->bgp_fs_pbr && listcount(extra->bgp_fs_pbr)) {
                        struct listnode *node;
                        struct bgp_pbr_match_entry *bpme;
-                       struct bgp_pbr_rule *bpr;
                        struct bgp_pbr_match *bpm;
-                       bool list_began = false;
                        struct list *list_bpm;
 
                        list_bpm = list_new();
@@ -357,6 +355,14 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
                                        vty_out(vty, ", ");
                                vty_out(vty, "%s", bpm->ipset_name);
                        }
+                       list_delete(&list_bpm);
+               }
+               if (extra->bgp_fs_iprule && listcount(extra->bgp_fs_iprule)) {
+                       struct listnode *node;
+                       struct bgp_pbr_rule *bpr;
+
+                       if (!list_began)
+                               vty_out(vty, "\tinstalled in PBR");
                        for (ALL_LIST_ELEMENTS_RO(extra->bgp_fs_iprule,
                                                  node, bpr)) {
                                if (!bpr->action)
@@ -373,8 +379,8 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
                        if (list_began)
                                vty_out(vty, ")");
                        vty_out(vty, "\n");
-                       list_delete(&list_bpm);
-               } else
+               }
+               if (!list_began)
                        vty_out(vty, "\tnot installed in PBR\n");
        }
 }
index c0be36ed3f4ad3b9b7d8483bc275dc2ed1cfacbf..0fddfa75a1e88a87f33cd38cefeecc8529e1be3f 100644 (file)
@@ -1421,7 +1421,8 @@ static void bgp_pbr_flush_iprule(struct bgp *bgp, struct bgp_pbr_action *bpa,
                        /* unlink path to bpme */
                        path = (struct bgp_path_info *)bpr->path;
                        extra = bgp_path_info_extra_get(path);
-                       listnode_delete(extra->bgp_fs_iprule, bpr);
+                       if (extra->bgp_fs_iprule)
+                               listnode_delete(extra->bgp_fs_iprule, bpr);
                        bpr->path = NULL;
                }
        }
@@ -1458,7 +1459,8 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
                        /* unlink path to bpme */
                        path = (struct bgp_path_info *)bpme->path;
                        extra = bgp_path_info_extra_get(path);
-                       listnode_delete(extra->bgp_fs_pbr, bpme);
+                       if (extra->bgp_fs_pbr)
+                               listnode_delete(extra->bgp_fs_pbr, bpme);
                        bpme->path = NULL;
                }
        }
@@ -2065,8 +2067,9 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
                        struct bgp_path_info_extra *extra =
                                bgp_path_info_extra_get(path);
 
-                       if (extra && listnode_lookup(extra->bgp_fs_iprule,
-                                                    bpr)) {
+                       if (extra &&
+                           listnode_lookup_nocheck(extra->bgp_fs_iprule,
+                                                   bpr)) {
                                if (BGP_DEBUG(pbr, PBR_ERROR))
                                        zlog_err("%s: entry %p/%p already "
                                                 "installed in bgp pbr iprule",
@@ -2213,7 +2216,8 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
                struct bgp_path_info_extra *extra =
                        bgp_path_info_extra_get(path);
 
-               if (extra && listnode_lookup(extra->bgp_fs_pbr, bpme)) {
+               if (extra &&
+                   listnode_lookup_nocheck(extra->bgp_fs_pbr, bpme)) {
                        if (BGP_DEBUG(pbr, PBR_ERROR))
                                zlog_err(
                                        "%s: entry %p/%p already installed in bgp pbr",
index e8a8e561503596fc611cac3f69ee9db393bbe62c..7036ededac405dae3f24c2e38920bb6dd76e2edb 100644 (file)
@@ -175,8 +175,8 @@ static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
                      sizeof(struct bgp_path_info_extra));
        new->label[0] = MPLS_INVALID_LABEL;
        new->num_labels = 0;
-       new->bgp_fs_pbr = list_new();
-       new->bgp_fs_iprule = list_new();
+       new->bgp_fs_pbr = NULL;
+       new->bgp_fs_iprule = NULL;
        return new;
 }
 
index 66fcbb3f3afa9ed82a79b676985b45bcbb6d116e..55ecc5f16ced7588268e613ded1410ceb2b0eb5b 100644 (file)
@@ -2153,7 +2153,8 @@ static int rule_notify_owner(int command, struct zclient *zclient,
                        /* link bgp_info to bgp_pbr */
                        path = (struct bgp_path_info *)bgp_pbr->path;
                        extra = bgp_path_info_extra_get(path);
-                       listnode_add(extra->bgp_fs_iprule, bgp_pbr);
+                       listnode_add_force(&extra->bgp_fs_iprule,
+                                          bgp_pbr);
                }
                if (BGP_DEBUG(zebra, ZEBRA))
                        zlog_debug("%s: Received RULE_INSTALLED",
@@ -2261,7 +2262,7 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient,
                /* link bgp_path_info to bpme */
                path = (struct bgp_path_info *)bgp_pbime->path;
                extra = bgp_path_info_extra_get(path);
-               listnode_add(extra->bgp_fs_pbr, bgp_pbime);
+               listnode_add_force(&extra->bgp_fs_pbr, bgp_pbime);
                }
                break;
        case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
index ab5faf76b6c11afb5c10e8d131365cae7fb0b0c0..52f68eff5ab693928b554b1459590efbac7d4920 100644 (file)
@@ -1000,7 +1000,7 @@ DEFPY(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd,
 DEFPY(isis_default_originate, isis_default_originate_cmd,
       "[no] default-information originate <ipv4|ipv6>$ip"
       " <level-1|level-2>$level [always]$always"
-      " [<metric (0-16777215)$metric|route-map WORD$rmap>]",
+      " [{metric (0-16777215)$metric|route-map WORD$rmap}]",
       NO_STR
       "Control distribution of default information\n"
       "Distribute a default route\n"
@@ -1023,9 +1023,8 @@ DEFPY(isis_default_originate, isis_default_originate_cmd,
                nb_cli_enqueue_change(vty, "./route-map",
                                      rmap ? NB_OP_MODIFY : NB_OP_DESTROY,
                                      rmap ? rmap : NULL);
-               nb_cli_enqueue_change(vty, "./metric",
-                                     metric ? NB_OP_MODIFY : NB_OP_DESTROY,
-                                     metric ? metric_str : NULL);
+               nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
+                                     metric_str ? metric_str : NULL);
                if (strmatch(ip, "ipv6") && !always) {
                        vty_out(vty,
                                "Zebra doesn't implement default-originate for IPv6 yet\n");
@@ -1043,8 +1042,6 @@ static void vty_print_def_origin(struct vty *vty, struct lyd_node *dnode,
                                 const char *family, const char *level,
                                 bool show_defaults)
 {
-       const char *metric;
-
        vty_out(vty, " default-information originate %s %s", family, level);
        if (yang_dnode_get_bool(dnode, "./always"))
                vty_out(vty, " always");
@@ -1052,11 +1049,10 @@ static void vty_print_def_origin(struct vty *vty, struct lyd_node *dnode,
        if (yang_dnode_exists(dnode, "./route-map"))
                vty_out(vty, " route-map %s",
                        yang_dnode_get_string(dnode, "./route-map"));
-       else if (yang_dnode_exists(dnode, "./metric")) {
-               metric = yang_dnode_get_string(dnode, "./metric");
-               if (show_defaults || !yang_dnode_is_default(dnode, "./metric"))
-                       vty_out(vty, " metric %s", metric);
-       }
+       if (show_defaults || !yang_dnode_is_default(dnode, "./metric"))
+               vty_out(vty, " metric %s",
+                       yang_dnode_get_string(dnode, "./metric"));
+
        vty_out(vty, "\n");
 }
 
@@ -1083,7 +1079,7 @@ DEFPY(isis_redistribute, isis_redistribute_cmd,
       "[no] redistribute <ipv4|ipv6>$ip " PROTO_REDIST_STR
       "$proto"
       " <level-1|level-2>$level"
-      " [<metric (0-16777215)|route-map WORD>]",
+      " [{metric (0-16777215)|route-map WORD}]",
       NO_STR REDIST_STR
       "Redistribute IPv4 routes\n"
       "Redistribute IPv6 routes\n" PROTO_REDIST_HELP
@@ -1101,9 +1097,8 @@ DEFPY(isis_redistribute, isis_redistribute_cmd,
                nb_cli_enqueue_change(vty, "./route-map",
                                      route_map ? NB_OP_MODIFY : NB_OP_DESTROY,
                                      route_map ? route_map : NULL);
-               nb_cli_enqueue_change(vty, "./metric",
-                                     metric ? NB_OP_MODIFY : NB_OP_DESTROY,
-                                     metric ? metric_str : NULL);
+               nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
+                                     metric_str ? metric_str : NULL);
        }
 
        return nb_cli_apply_changes(
@@ -1112,16 +1107,16 @@ DEFPY(isis_redistribute, isis_redistribute_cmd,
 }
 
 static void vty_print_redistribute(struct vty *vty, struct lyd_node *dnode,
-                                  const char *family)
+                                  bool show_defaults, const char *family)
 {
        const char *level = yang_dnode_get_string(dnode, "./level");
        const char *protocol = yang_dnode_get_string(dnode, "./protocol");
 
        vty_out(vty, " redistribute %s %s %s", family, protocol, level);
-       if (yang_dnode_exists(dnode, "./metric"))
+       if (show_defaults || !yang_dnode_is_default(dnode, "./metric"))
                vty_out(vty, " metric %s",
                        yang_dnode_get_string(dnode, "./metric"));
-       else if (yang_dnode_exists(dnode, "./route-map"))
+       if (yang_dnode_exists(dnode, "./route-map"))
                vty_out(vty, " route-map %s",
                        yang_dnode_get_string(dnode, "./route-map"));
        vty_out(vty, "\n");
@@ -1130,12 +1125,12 @@ static void vty_print_redistribute(struct vty *vty, struct lyd_node *dnode,
 void cli_show_isis_redistribute_ipv4(struct vty *vty, struct lyd_node *dnode,
                                     bool show_defaults)
 {
-       vty_print_redistribute(vty, dnode, "ipv4");
+       vty_print_redistribute(vty, dnode, show_defaults, "ipv4");
 }
 void cli_show_isis_redistribute_ipv6(struct vty *vty, struct lyd_node *dnode,
                                     bool show_defaults)
 {
-       vty_print_redistribute(vty, dnode, "ipv6");
+       vty_print_redistribute(vty, dnode, show_defaults, "ipv6");
 }
 
 /*
index 2d1d6f592702f757dcb84525f5a46885f911237c..8b26a7397549ff1fea88ff6e9983c532a33cd3ce 100644 (file)
@@ -826,7 +826,7 @@ static void default_info_origin_apply_finish(const struct lyd_node *dnode,
 
        if (yang_dnode_exists(dnode, "./metric"))
                metric = yang_dnode_get_uint32(dnode, "./metric");
-       else if (yang_dnode_exists(dnode, "./route-map"))
+       if (yang_dnode_exists(dnode, "./route-map"))
                routemap = yang_dnode_get_string(dnode, "./route-map");
 
        isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
@@ -907,13 +907,6 @@ static int isis_instance_default_information_originate_ipv4_metric_modify(
        return NB_OK;
 }
 
-static int isis_instance_default_information_originate_ipv4_metric_destroy(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       /* It's all done by default_info_origin_apply_finish */
-       return NB_OK;
-}
-
 /*
  * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6
  */
@@ -981,13 +974,6 @@ static int isis_instance_default_information_originate_ipv6_metric_modify(
        return NB_OK;
 }
 
-static int isis_instance_default_information_originate_ipv6_metric_destroy(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       /* It's all done by default_info_origin_apply_finish */
-       return NB_OK;
-}
-
 /*
  * XPath: /frr-isisd:isis/instance/redistribute/ipv4
  */
@@ -1005,7 +991,7 @@ static void redistribute_apply_finish(const struct lyd_node *dnode, int family)
 
        if (yang_dnode_exists(dnode, "./metric"))
                metric = yang_dnode_get_uint32(dnode, "./metric");
-       else if (yang_dnode_exists(dnode, "./route-map"))
+       if (yang_dnode_exists(dnode, "./route-map"))
                routemap = yang_dnode_get_string(dnode, "./route-map");
 
        isis_redist_set(area, level, family, type, metric, routemap, 0);
@@ -1078,14 +1064,6 @@ isis_instance_redistribute_ipv4_metric_modify(enum nb_event event,
        return NB_OK;
 }
 
-static int
-isis_instance_redistribute_ipv4_metric_destroy(enum nb_event event,
-                                             const struct lyd_node *dnode)
-{
-       /* It's all done by redistribute_apply_finish */
-       return NB_OK;
-}
-
 /*
  * XPath: /frr-isisd:isis/instance/redistribute/ipv6
  */
@@ -1146,14 +1124,6 @@ isis_instance_redistribute_ipv6_metric_modify(enum nb_event event,
        return NB_OK;
 }
 
-static int
-isis_instance_redistribute_ipv6_metric_destroy(enum nb_event event,
-                                             const struct lyd_node *dnode)
-{
-       /* It's all done by redistribute_apply_finish */
-       return NB_OK;
-}
-
 /*
  * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast
  */
@@ -2926,7 +2896,6 @@ const struct frr_yang_module_info frr_isisd_info = {
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/metric",
                        .cbs.modify = isis_instance_default_information_originate_ipv4_metric_modify,
-                       .cbs.destroy = isis_instance_default_information_originate_ipv4_metric_destroy,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6",
@@ -2947,7 +2916,6 @@ const struct frr_yang_module_info frr_isisd_info = {
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/metric",
                        .cbs.modify = isis_instance_default_information_originate_ipv6_metric_modify,
-                       .cbs.destroy = isis_instance_default_information_originate_ipv6_metric_destroy,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/redistribute/ipv4",
@@ -2964,7 +2932,6 @@ const struct frr_yang_module_info frr_isisd_info = {
                {
                        .xpath = "/frr-isisd:isis/instance/redistribute/ipv4/metric",
                        .cbs.modify = isis_instance_redistribute_ipv4_metric_modify,
-                       .cbs.destroy = isis_instance_redistribute_ipv4_metric_destroy,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/redistribute/ipv6",
@@ -2981,7 +2948,6 @@ const struct frr_yang_module_info frr_isisd_info = {
                {
                        .xpath = "/frr-isisd:isis/instance/redistribute/ipv6/metric",
                        .cbs.modify = isis_instance_redistribute_ipv6_metric_modify,
-                       .cbs.destroy = isis_instance_redistribute_ipv6_metric_destroy,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-multicast",
index 3a864fb356c658eb604f6bf5d7f0ed3480abc5c8..9047707bf0dfb1bce2f5c86403c81292b955a09e 100644 (file)
@@ -516,7 +516,7 @@ void isis_redist_area_finish(struct isis_area *area)
 DEFUN (isis_redistribute,
        isis_redistribute_cmd,
        "redistribute <ipv4|ipv6> " PROTO_REDIST_STR
-       " [<metric (0-16777215)|route-map WORD>]",
+       " [{metric (0-16777215)|route-map WORD}]",
        REDIST_STR
        "Redistribute IPv4 routes\n"
        "Redistribute IPv6 routes\n"
@@ -528,7 +528,7 @@ DEFUN (isis_redistribute,
 {
        int idx_afi = 1;
        int idx_protocol = 2;
-       int idx_metric_rmap = fabricd ? 3 : 4;
+       int idx_metric_rmap = 1;
        VTY_DECLVAR_CONTEXT(isis_area, area);
        int family;
        int afi;
@@ -556,20 +556,13 @@ DEFUN (isis_redistribute,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       if (argc > idx_metric_rmap + 1) {
-               if (argv[idx_metric_rmap + 1]->arg[0] == '\0')
-                       return CMD_WARNING_CONFIG_FAILED;
-
-               if (strmatch(argv[idx_metric_rmap]->text, "metric")) {
-                       char *endp;
-                       metric = strtoul(argv[idx_metric_rmap + 1]->arg, &endp,
-                                        10);
+       if (argv_find(argv, argc, "metric", &idx_metric_rmap)) {
+               metric = strtoul(argv[idx_metric_rmap + 1]->arg, NULL, 10);
+       }
 
-                       if (*endp != '\0')
-                               return CMD_WARNING_CONFIG_FAILED;
-               } else {
-                       routemap = argv[idx_metric_rmap + 1]->arg;
-               }
+       idx_metric_rmap = 1;
+       if (argv_find(argv, argc, "route-map", &idx_metric_rmap)) {
+               routemap = argv[idx_metric_rmap + 1]->arg;
        }
 
        isis_redist_set(area, level, family, type, metric, routemap, 0);
@@ -614,7 +607,7 @@ DEFUN (no_isis_redistribute,
 DEFUN (isis_default_originate,
        isis_default_originate_cmd,
        "default-information originate <ipv4|ipv6>"
-       " [always] [<metric (0-16777215)|route-map WORD>]",
+       " [always] [{metric (0-16777215)|route-map WORD}]",
        "Control distribution of default information\n"
        "Distribute a default route\n"
        "Distribute default route for IPv4\n"
@@ -627,7 +620,7 @@ DEFUN (isis_default_originate,
 {
        int idx_afi = 2;
        int idx_always = fabricd ? 3 : 4;
-       int idx_metric_rmap = fabricd ? 3 : 4;
+       int idx_metric_rmap = 1;
        VTY_DECLVAR_CONTEXT(isis_area, area);
        int family;
        int originate_type = DEFAULT_ORIGINATE;
@@ -651,12 +644,13 @@ DEFUN (isis_default_originate,
                idx_metric_rmap++;
        }
 
-       if (argc > idx_metric_rmap) {
-               if (strmatch(argv[idx_metric_rmap]->text, "metric"))
-                       metric = strtoul(argv[idx_metric_rmap + 1]->arg, NULL,
-                                        10);
-               else
-                       routemap = argv[idx_metric_rmap + 1]->arg;
+       if (argv_find(argv, argc, "metric", &idx_metric_rmap)) {
+               metric = strtoul(argv[idx_metric_rmap + 1]->arg, NULL, 10);
+       }
+
+       idx_metric_rmap = 1;
+       if (argv_find(argv, argc, "route-map", &idx_metric_rmap)) {
+               routemap = argv[idx_metric_rmap + 1]->arg;
        }
 
        if (family == AF_INET6 && originate_type != DEFAULT_ORIGINATE_ALWAYS) {
index 3aa7cae8b714c7c8d8eeecb9b7aa426ea05e4dca..f0d0c292450c5dadf8d2586c0d42613a7d854546 100644 (file)
@@ -259,6 +259,13 @@ struct listnode *listnode_lookup(struct list *list, void *data)
        return NULL;
 }
 
+struct listnode *listnode_lookup_nocheck(struct list *list, void *data)
+{
+       if (!list)
+               return NULL;
+       return listnode_lookup(list, data);
+}
+
 void list_delete_node(struct list *list, struct listnode *node)
 {
        if (node->prev)
@@ -318,3 +325,10 @@ void list_sort(struct list *list, int (*cmp)(const void **, const void **))
 
        XFREE(MTYPE_TMP, items);
 }
+
+void listnode_add_force(struct list **list, void *val)
+{
+       if (*list == NULL)
+               *list = list_new();
+       return listnode_add(*list, val);
+}
index 76fad45d0861c36ac99657ea660c5b2c16fd61cf..e75d86343100567b93d045a7d62956fed55ee16e 100644 (file)
@@ -341,6 +341,10 @@ extern void list_add_list(struct list *list, struct list *add);
                (L)->count--;                                                  \
        } while (0)
 
+extern struct listnode *listnode_lookup_nocheck(struct list *list, void *data);
+
+extern void listnode_add_force(struct list **list, void *val);
+
 #ifdef __cplusplus
 }
 #endif
index e1898ead225abe1793dfa9c3f504cb27c6e42a8b..de50e6a51743726e97d07a2113ee196996f06b26 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -542,35 +542,6 @@ void vrf_terminate(void)
        }
 }
 
-static int vrf_default_accepts_vrf(int type)
-{
-       const char *fname = NULL;
-       char buf[32] = {0x0};
-       int ret = 0;
-       FILE *fd = NULL;
-
-       /*
-        * TCP & UDP services running in the default VRF context (ie., not bound
-        * to any VRF device) can work across all VRF domains by enabling the
-        * tcp_l3mdev_accept and udp_l3mdev_accept sysctl options:
-        * sysctl -w net.ipv4.tcp_l3mdev_accept=1
-        * sysctl -w net.ipv4.udp_l3mdev_accept=1
-        */
-       if (type == SOCK_STREAM)
-               fname = "/proc/sys/net/ipv4/tcp_l3mdev_accept";
-       else if (type == SOCK_DGRAM)
-               fname = "/proc/sys/net/ipv4/udp_l3mdev_accept";
-       else
-               return ret;
-       fd = fopen(fname, "r");
-       if (fd == NULL)
-               return ret;
-       fgets(buf, 32, fd);
-       ret = atoi(buf);
-       fclose(fd);
-       return ret;
-}
-
 /* Create a socket for the VRF. */
 int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
               const char *interfacename)
@@ -582,13 +553,6 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
                flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
                             __func__, vrf_id, safe_strerror(errno));
 
-       if (ret > 0 && interfacename && vrf_default_accepts_vrf(type)) {
-               zlog_err("VRF socket not used since net.ipv4.%s_l3mdev_accept != 0",
-                         (type == SOCK_STREAM ? "tcp" : "udp"));
-               errno = EEXIST; /* not sure if this is the best error... */
-               return -2;
-       }
-
        ret = socket(domain, type, protocol);
        save_errno = errno;
        ret2 = vrf_switchback_to_initial();
index afeda723e26651ce2cfe3ff221a308b95f3885e4..2d5acb87a91b5fc9814659a7f2406812431c2b70 100644 (file)
@@ -4257,7 +4257,6 @@ DEFUN (show_ip_pim_nexthop_lookup,
        "Source/RP address\n"
        "Multicast Group address\n")
 {
-       struct pim_nexthop_cache *pnc = NULL;
        struct prefix nht_p;
        int result = 0;
        struct in_addr src_addr, grp_addr;
@@ -4269,7 +4268,6 @@ 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;
@@ -4315,18 +4313,7 @@ DEFUN (show_ip_pim_nexthop_lookup,
        grp.u.prefix4 = grp_addr;
        memset(&nexthop, 0, sizeof(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, &nht_p,
-                                                &grp, 0);
+       result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p, &grp, 0);
 
        if (!result) {
                vty_out(vty,
index 5e550dfe853558084cd8c2c0528623d6963436d5..8a459fe86e57325183e6a9f0d6c00c541f42a041 100644 (file)
@@ -158,7 +158,8 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
                hash_get(pnc->upstream_hash, up, hash_alloc_intern);
 
        if (CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID)) {
-               memcpy(out_pnc, pnc, sizeof(struct pim_nexthop_cache));
+               if (out_pnc)
+                       memcpy(out_pnc, pnc, sizeof(struct pim_nexthop_cache));
                return 1;
        }
 
@@ -256,10 +257,9 @@ static void pim_update_rp_nh(struct pim_instance *pim,
                        continue;
 
                // Compute PIM RPF using cached nexthop
-               if (!pim_ecmp_nexthop_search(pim, pnc,
-                   &rp_info->rp.source_nexthop,
-                   &rp_info->rp.rpf_addr, &rp_info->group,
-                   1))
+               if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
+                                            &rp_info->rp.rpf_addr,
+                                            &rp_info->group, 1))
                        pim_rp_nexthop_del(rp_info);
        }
 }
@@ -347,10 +347,11 @@ uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp)
        return hash_val;
 }
 
-int pim_ecmp_nexthop_search(struct pim_instance *pim,
-                           struct pim_nexthop_cache *pnc,
-                           struct pim_nexthop *nexthop, struct prefix *src,
-                           struct prefix *grp, int neighbor_needed)
+static int pim_ecmp_nexthop_search(struct pim_instance *pim,
+                                  struct pim_nexthop_cache *pnc,
+                                  struct pim_nexthop *nexthop,
+                                  struct prefix *src, struct prefix *grp,
+                                  int neighbor_needed)
 {
        struct pim_neighbor *nbrs[MULTIPATH_NUM], *nbr = NULL;
        struct interface *ifps[MULTIPATH_NUM];
@@ -709,6 +710,7 @@ int pim_parse_nexthop_update(int command, struct zclient *zclient,
                nexthops_free(pnc->nexthop);
                pnc->nexthop = NULL;
        }
+       SET_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED);
 
        if (PIM_DEBUG_PIM_NHT) {
                char buf[PREFIX2STR_BUFFER];
@@ -734,8 +736,10 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
                            struct pim_nexthop *nexthop, struct prefix *src,
                            struct prefix *grp, int neighbor_needed)
 {
+       struct pim_nexthop_cache *pnc;
        struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
        struct pim_neighbor *nbrs[MULTIPATH_NUM], *nbr = NULL;
+       struct pim_rpf rpf;
        int num_ifindex;
        struct interface *ifps[MULTIPATH_NUM], *ifp;
        int first_ifindex;
@@ -753,6 +757,18 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
                           nexthop->last_lookup_time);
        }
 
+       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 = src->u.prefix4;
+
+       pnc = pim_nexthop_cache_find(pim, &rpf);
+       if (pnc) {
+               if (CHECK_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED))
+                   return pim_ecmp_nexthop_search(pim, pnc, nexthop, src, grp,
+                                                  neighbor_needed);
+       }
+
        memset(nexthop_tab, 0,
               sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM);
        num_ifindex =
@@ -899,6 +915,8 @@ int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
        if (PIM_DEBUG_PIM_NHT)
                pim_inet4_dump("<addr?>", src->u.prefix4, addr_str,
                               sizeof(addr_str));
+
+       memset(&nhop, 0, sizeof(nhop));
        if (!pim_ecmp_nexthop_lookup(pim, &nhop, src, grp, 0)) {
                if (PIM_DEBUG_PIM_NHT)
                        zlog_debug(
index e3e9f578c9f151708ab4fca823ad2edf07afda6c..13bb0fcb55cfde5ba68564149e631a140f9784da 100644 (file)
@@ -41,6 +41,7 @@ struct pim_nexthop_cache {
        int64_t last_update;
        uint16_t flags;
 #define PIM_NEXTHOP_VALID             (1 << 0)
+#define PIM_NEXTHOP_ANSWER_RECEIVED   (1 << 1)
 
        struct list *rp_list;
        struct hash *upstream_hash;
@@ -56,10 +57,6 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
 struct pim_nexthop_cache *pim_nexthop_cache_find(struct pim_instance *pim,
                                                 struct pim_rpf *rpf);
 uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp);
-int pim_ecmp_nexthop_search(struct pim_instance *pim,
-                           struct pim_nexthop_cache *pnc,
-                           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 prefix *src,
                            struct prefix *grp, int neighbor_needed);
index 4e285720a205694a237d6fe4326420deed052e7c..14643743ad8fc4fd28f7c38f0beabc7b81244d17 100644 (file)
@@ -418,7 +418,6 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
        char buffer[BUFSIZ];
        struct prefix nht_p;
        struct prefix temp;
-       struct pim_nexthop_cache pnc;
        struct route_node *rn;
        struct pim_upstream *up;
        struct listnode *upnode;
@@ -564,22 +563,16 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
                                }
                        }
 
-                       memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
-                       if (pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_all,
-                                                     &pnc)) {
-                               if (!pim_ecmp_nexthop_search(
-                                           pim, &pnc,
-                                           &rp_all->rp.source_nexthop, &nht_p,
-                                           &rp_all->group, 1))
-                                       return PIM_RP_NO_PATH;
-                       } else {
-                               if (!pim_ecmp_nexthop_lookup(
-                                           pim, &rp_all->rp.source_nexthop,
-                                           &nht_p, &rp_all->group, 1))
-                                       return PIM_RP_NO_PATH;
-                       }
                        pim_rp_check_interfaces(pim, rp_all);
                        pim_rp_refresh_group_to_rp_mapping(pim);
+
+                       pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_all,
+                                                 NULL);
+                       if (!pim_ecmp_nexthop_lookup(pim,
+                                                    &rp_all->rp.source_nexthop,
+                                                    &nht_p, &rp_all->group, 1))
+                               return PIM_RP_NO_PATH;
+
                        return PIM_SUCCESS;
                }
 
@@ -646,6 +639,9 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
                }
        }
 
+       pim_rp_check_interfaces(pim, rp_info);
+       pim_rp_refresh_group_to_rp_mapping(pim);
+
        /* Register addr with Zebra NHT */
        nht_p.family = AF_INET;
        nht_p.prefixlen = IPV4_MAX_BITLEN;
@@ -659,20 +655,11 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
                           __PRETTY_FUNCTION__, buf, buf1);
        }
 
-       memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
-       if (pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, &pnc)) {
-               if (!pim_ecmp_nexthop_search(pim, &pnc,
-                                            &rp_info->rp.source_nexthop,
-                                            &nht_p, &rp_info->group, 1))
-                       return PIM_RP_NO_PATH;
-       } else {
-               if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
-                                            &nht_p, &rp_info->group, 1))
-                       return PIM_RP_NO_PATH;
-       }
+       pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, NULL);
+       if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, &nht_p,
+                                    &rp_info->group, 1))
+               return PIM_RP_NO_PATH;
 
-       pim_rp_check_interfaces(pim, rp_info);
-       pim_rp_refresh_group_to_rp_mapping(pim);
        return PIM_SUCCESS;
 }
 
@@ -823,7 +810,6 @@ void pim_rp_setup(struct pim_instance *pim)
        struct listnode *node;
        struct rp_info *rp_info;
        struct prefix nht_p;
-       struct pim_nexthop_cache pnc;
 
        for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) {
                if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE)
@@ -832,27 +818,13 @@ void pim_rp_setup(struct pim_instance *pim)
                nht_p.family = AF_INET;
                nht_p.prefixlen = IPV4_MAX_BITLEN;
                nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
-               memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
-               if (pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, &pnc))
-                       pim_ecmp_nexthop_search(pim, &pnc,
-                                               &rp_info->rp.source_nexthop,
-                                               &nht_p, &rp_info->group, 1);
-               else {
-                       if (PIM_DEBUG_PIM_NHT_RP) {
-                               char buf[PREFIX2STR_BUFFER];
 
-                               prefix2str(&nht_p, buf, sizeof(buf));
+               pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, NULL);
+               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(
-                                       "%s: NHT Local Nexthop not found for RP %s ",
-                                       __PRETTY_FUNCTION__, buf);
-                       }
-                       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");
-               }
+                                       "Unable to lookup nexthop for rp specified");
        }
 }
 
@@ -983,7 +955,7 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group)
 
        if (rp_info) {
                struct prefix nht_p;
-               struct pim_nexthop_cache pnc;
+
                /* Register addr with Zebra NHT */
                nht_p.family = AF_INET;
                nht_p.prefixlen = IPV4_MAX_BITLEN;
@@ -997,26 +969,11 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group)
                                "%s: NHT Register RP addr %s grp %s with Zebra",
                                __PRETTY_FUNCTION__, buf, buf1);
                }
-               memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
-               if (pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, &pnc))
-                       pim_ecmp_nexthop_search(pim, &pnc,
-                                               &rp_info->rp.source_nexthop,
-                                               &nht_p, &rp_info->group, 1);
-               else {
-                       if (PIM_DEBUG_PIM_NHT_RP) {
-                               char buf[PREFIX2STR_BUFFER];
-                               char buf1[PREFIX2STR_BUFFER];
-                               prefix2str(&nht_p, buf, sizeof(buf));
-                               prefix2str(&g, buf1, sizeof(buf1));
-                               zlog_debug(
-                                       "%s: Nexthop cache not found for RP %s grp %s register with Zebra",
-                                       __PRETTY_FUNCTION__, buf, buf1);
-                       }
-                       pim_rpf_set_refresh_time(pim);
-                       (void)pim_ecmp_nexthop_lookup(
-                               pim, &rp_info->rp.source_nexthop, &nht_p,
-                               &rp_info->group, 1);
-               }
+
+               pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, NULL);
+               pim_rpf_set_refresh_time(pim);
+               (void)pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
+                                             &nht_p, &rp_info->group, 1);
                return (&rp_info->rp);
        }
 
index 55f788b5bb8db373295f5a9a3f77c5209f1d2483..8cc8b7481cbb0a1ab34a7ff2b553c483524b7786 100644 (file)
@@ -201,7 +201,6 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
        struct pim_rpf *rpf = &up->rpf;
        struct pim_rpf saved;
        struct prefix nht_p;
-       struct pim_nexthop_cache pnc;
        struct prefix src, grp;
        bool neigh_needed = true;
 
@@ -232,23 +231,14 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
        grp.family = AF_INET;
        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, neigh_needed))
-                               return PIM_RPF_FAILURE;
-               }
-       } else {
-               if (!pim_ecmp_nexthop_lookup(pim, &rpf->source_nexthop, &src,
-                                            &grp, neigh_needed))
-                       return PIM_RPF_FAILURE;
-       }
+       pim_find_or_track_nexthop(pim, &nht_p, up, NULL, NULL);
+       if (!pim_ecmp_nexthop_lookup(pim, &rpf->source_nexthop, &src, &grp,
+                                    neigh_needed))
+               return PIM_RPF_FAILURE;
 
        rpf->rpf_addr.family = AF_INET;
        rpf->rpf_addr.u.prefix4 = pim_rpf_find_rpf_addr(up);
index f1347b7eafeaf5a344502efa00ab079635b35216..04137b0b78cd311c704f0176aef55c9cbfafb03b 100644 (file)
@@ -1297,11 +1297,15 @@ void pim_upstream_set_sptbit(struct pim_upstream *up,
        if (!starup
            || up->rpf.source_nexthop
                               .interface != starup->rpf.source_nexthop.interface) {
+               struct pim_upstream *starup = up->parent;
+
                if (PIM_DEBUG_TRACE)
                        zlog_debug(
                                "%s: %s RPF_interface(S) != RPF_interface(RP(G))",
                                __PRETTY_FUNCTION__, up->sg_str);
                up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+
+               pim_jp_agg_single_upstream_send(&starup->rpf, starup, true);
                return;
        }
 
index 70f099b0d78d2c73b24bf53efd9b04ceb736d079..4ef158496655ac83c2fad6501d8a072dee5be728 100644 (file)
@@ -929,7 +929,6 @@ void igmp_source_forward_start(struct pim_instance *pim,
        if (!source->source_channel_oil) {
                struct in_addr vif_source;
                struct prefix nht_p, src, grp;
-               struct pim_nexthop_cache out_pnc;
                struct pim_nexthop nexthop;
                struct pim_upstream *up = NULL;
 
@@ -955,7 +954,6 @@ void igmp_source_forward_start(struct pim_instance *pim,
                        nht_p.family = AF_INET;
                        nht_p.prefixlen = IPV4_MAX_BITLEN;
                        nht_p.u.prefix4 = vif_source;
-                       memset(&out_pnc, 0, sizeof(struct pim_nexthop_cache));
 
                        src.family = AF_INET;
                        src.prefixlen = IPV4_MAX_BITLEN;
@@ -964,44 +962,21 @@ void igmp_source_forward_start(struct pim_instance *pim,
                        grp.prefixlen = IPV4_MAX_BITLEN;
                        grp.u.prefix4 = sg.grp;
 
-                       if (pim_find_or_track_nexthop(pim, &nht_p, NULL, NULL,
-                                             &out_pnc)) {
-                               if (out_pnc.nexthop_num) {
-                                       up = pim_upstream_find(pim, &sg);
-                                       memset(&nexthop, 0, sizeof(nexthop));
-                                       if (up)
-                                               memcpy(&nexthop,
-                                                   &up->rpf.source_nexthop,
-                                                   sizeof(struct pim_nexthop));
-                                       pim_ecmp_nexthop_search(pim, &out_pnc,
-                                                               &nexthop,
-                                                               &src, &grp, 0);
-                                       if (nexthop.interface)
-                                               input_iface_vif_index =
+                       up = pim_upstream_find(pim, &sg);
+                       if (up) {
+                               memcpy(&nexthop, &up->rpf.source_nexthop,
+                                      sizeof(struct pim_nexthop));
+                               pim_ecmp_nexthop_lookup(pim, &nexthop, &src,
+                                                       &grp, 0);
+                               if (nexthop.interface)
+                                       input_iface_vif_index =
                                                pim_if_find_vifindex_by_ifindex(
-                                                   pim,
-                                                   nexthop.interface->ifindex);
-                               } else {
-                                       if (PIM_DEBUG_ZEBRA) {
-                                               char buf1[INET_ADDRSTRLEN];
-                                               char buf2[INET_ADDRSTRLEN];
-
-                                               pim_inet4_dump("<source?>",
-                                                      nht_p.u.prefix4, buf1,
-                                                      sizeof(buf1));
-                                               pim_inet4_dump("<source?>",
-                                                      grp.u.prefix4, buf2,
-                                                      sizeof(buf2));
-                                               zlog_debug(
-                                               "%s: NHT Nexthop not found for addr %s grp %s",
-                                               __PRETTY_FUNCTION__, buf1,
-                                               buf2);
-                                       }
-                               }
+                                                       pim,
+                                                       nexthop.interface->ifindex);
                        } else
                                input_iface_vif_index =
-                                   pim_ecmp_fib_lookup_if_vif_index(pim, &src,
-                                                                &grp);
+                                       pim_ecmp_fib_lookup_if_vif_index(
+                                               pim, &src, &grp);
 
                        if (PIM_DEBUG_ZEBRA) {
                                char buf2[INET_ADDRSTRLEN];
@@ -1209,7 +1184,6 @@ void pim_forward_start(struct pim_ifchannel *ch)
        */
        if ((up->upstream_addr.s_addr != INADDR_ANY) && (!up->channel_oil)) {
                struct prefix nht_p, src, grp;
-               struct pim_nexthop_cache out_pnc;
 
                /* Register addr with Zebra NHT */
                nht_p.family = AF_INET;
@@ -1218,55 +1192,14 @@ void pim_forward_start(struct pim_ifchannel *ch)
                grp.family = AF_INET;
                grp.prefixlen = IPV4_MAX_BITLEN;
                grp.u.prefix4 = up->sg.grp;
-               memset(&out_pnc, 0, sizeof(struct pim_nexthop_cache));
-
-               if (pim_find_or_track_nexthop(pim, &nht_p, NULL, NULL,
-                                             &out_pnc)) {
-                       if (out_pnc.nexthop_num) {
-                               src.family = AF_INET;
-                               src.prefixlen = IPV4_MAX_BITLEN;
-                               src.u.prefix4 =
-                                       up->upstream_addr; // RP or Src address
-                               grp.family = AF_INET;
-                               grp.prefixlen = IPV4_MAX_BITLEN;
-                               grp.u.prefix4 = up->sg.grp;
-                               // Compute PIM RPF using Cached nexthop
-                               if (pim_ecmp_nexthop_search(
-                                           pim, &out_pnc,
-                                           &up->rpf.source_nexthop, &src, &grp,
-                                           0))
-                                       input_iface_vif_index =
-                                               pim_if_find_vifindex_by_ifindex(
-                                                       pim,
-                                                       up->rpf.source_nexthop
-                                                               .interface->ifindex);
-                               else {
-                                       if (PIM_DEBUG_TRACE)
-                                               zlog_debug(
-                                                       "%s: Nexthop selection failed for %s ",
-                                                       __PRETTY_FUNCTION__,
-                                                       up->sg_str);
-                               }
-                       } else {
-                               if (PIM_DEBUG_ZEBRA) {
-                                       char buf1[INET_ADDRSTRLEN];
-                                       char buf2[INET_ADDRSTRLEN];
-                                       pim_inet4_dump("<source?>",
-                                                      nht_p.u.prefix4, buf1,
-                                                      sizeof(buf1));
-                                       pim_inet4_dump("<source?>",
-                                                      grp.u.prefix4, buf2,
-                                                      sizeof(buf2));
-                                       zlog_debug(
-                                               "%s: NHT pnc is NULL for addr %s grp %s",
-                                               __PRETTY_FUNCTION__, buf1,
-                                               buf2);
-                               }
-                       }
-               } else
-                       input_iface_vif_index =
-                               pim_ecmp_fib_lookup_if_vif_index(pim, &src,
-                                                                &grp);
+               src.family = AF_INET;
+               src.prefixlen = IPV4_MAX_BITLEN;
+               src.u.prefix4 = up->sg.src;
+
+               if (pim_ecmp_nexthop_lookup(pim, &up->rpf.source_nexthop, &src,
+                                           &grp, 0))
+                       input_iface_vif_index = pim_if_find_vifindex_by_ifindex(
+                               pim, up->rpf.source_nexthop.interface->ifindex);
 
                if (input_iface_vif_index < 1) {
                        if (PIM_DEBUG_PIM_TRACE) {
index 32b4d3acf6a57f7c9f829d84037fcb8973a237c6..d0d11c867636c36c2344e82ea007e782aadf1075 100644 (file)
@@ -179,25 +179,23 @@ module frr-isisd {
   grouping redistribute-attributes {
     description
       "Common optional attributes of any redistribute entry.";
-    choice attribute {
-      leaf route-map {
-        type string {
-          length "1..max";
-        }
-        description
-          "Applies the conditions of the specified route-map to routes that
-           are redistributed into this routing instance.";
+    leaf route-map {
+      type string {
+        length "1..max";
       }
+      description
+        "Applies the conditions of the specified route-map to routes that
+         are redistributed into this routing instance.";
+    }
 
-      leaf metric {
-        type uint32 {
-          range "0..16777215";
-        }
-        default "0";
-        description
-          "Metric used for the redistributed route. If 0,
-           the default-metric attribute is used instead.";
+    leaf metric {
+      type uint32 {
+        range "0..16777215";
       }
+      default "0";
+      description
+        "Metric used for the redistributed route. If 0,
+         the default-metric attribute is used instead.";
     }
   }
 
@@ -737,13 +735,6 @@ module frr-isisd {
           "Area-tag associated to this circuit.";
       }
 
-      leaf circuit-type {
-        type level;
-        default "level-1-2";
-        description
-          "IS-type of this circuit.";
-      }
-
       leaf ipv4-routing {
         type boolean;
         default "false";
@@ -758,6 +749,13 @@ module frr-isisd {
           "Routing IS-IS IPv6 traffic over this circuit.";
       }
 
+      leaf circuit-type {
+        type level;
+        default "level-1-2";
+        description
+          "IS-type of this circuit.";
+      }
+
       container csnp-interval {
         description
           "Complete Sequence Number PDU (CSNP) generation interval.";
index 3d1ff676a5ff322cf3a8b9ff7d90df24baa1e85c..af54c3b5c7bd31bc8dfc738bce5f9c39759e15b2 100644 (file)
@@ -246,6 +246,9 @@ static struct zebra_dplane_globals {
        /* Limit number of pending, unprocessed updates */
        _Atomic uint32_t dg_max_queued_updates;
 
+       /* Control whether system route notifications should be produced. */
+       bool dg_sys_route_notifs;
+
        /* Limit number of new updates dequeued at once, to pace an
         * incoming burst.
         */
@@ -326,6 +329,12 @@ static struct zebra_dplane_ctx *dplane_ctx_alloc(void)
        return p;
 }
 
+/* Enable system route notifications */
+void dplane_enable_sys_route_notifs(void)
+{
+       zdplane_info.dg_sys_route_notifs = true;
+}
+
 /*
  * Free a dataplane results context.
  */
@@ -347,6 +356,8 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
        case DPLANE_OP_ROUTE_INSTALL:
        case DPLANE_OP_ROUTE_UPDATE:
        case DPLANE_OP_ROUTE_DELETE:
+       case DPLANE_OP_SYS_ROUTE_ADD:
+       case DPLANE_OP_SYS_ROUTE_DELETE:
 
                /* Free allocated nexthops */
                if ((*pctx)->u.rinfo.zd_ng.nexthop) {
@@ -532,6 +543,12 @@ const char *dplane_op2str(enum dplane_op_e op)
                ret = "PW_UNINSTALL";
                break;
 
+       case DPLANE_OP_SYS_ROUTE_ADD:
+               ret = "SYS_ROUTE_ADD";
+               break;
+       case DPLANE_OP_SYS_ROUTE_DELETE:
+               ret = "SYS_ROUTE_DEL";
+               break;
        }
 
        return ret;
@@ -962,21 +979,25 @@ static int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx,
        ctx->u.rinfo.zd_afi = info->afi;
        ctx->u.rinfo.zd_safi = info->safi;
 
-       /* Extract ns info - can't use pointers to 'core' structs */
-       zvrf = vrf_info_lookup(re->vrf_id);
-       zns = zvrf->zns;
-
-       dplane_ctx_ns_init(ctx, zns, (op == DPLANE_OP_ROUTE_UPDATE));
-
        /* Copy nexthops; recursive info is included too */
        copy_nexthops(&(ctx->u.rinfo.zd_ng.nexthop), re->ng.nexthop, NULL);
 
-       /* TODO -- maybe use array of nexthops to avoid allocs? */
-
        /* Ensure that the dplane's nexthops flags are clear. */
        for (ALL_NEXTHOPS(ctx->u.rinfo.zd_ng, nexthop))
                UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
 
+       /* Don't need some info when capturing a system notification */
+       if (op == DPLANE_OP_SYS_ROUTE_ADD ||
+           op == DPLANE_OP_SYS_ROUTE_DELETE) {
+               ret = AOK;
+               goto done;
+       }
+
+       /* Extract ns info - can't use pointers to 'core' structs */
+       zvrf = vrf_info_lookup(re->vrf_id);
+       zns = zvrf->zns;
+       dplane_ctx_ns_init(ctx, zns, (op == DPLANE_OP_ROUTE_UPDATE));
+
        /* Trying out the sequence number idea, so we can try to detect
         * when a result is stale.
         */
@@ -1296,6 +1317,54 @@ done:
        return ret;
 }
 
+/*
+ * Notify the dplane when system/connected routes change.
+ */
+enum zebra_dplane_result dplane_sys_route_add(struct route_node *rn,
+                                             struct route_entry *re)
+{
+       enum zebra_dplane_result ret = ZEBRA_DPLANE_REQUEST_FAILURE;
+
+       /* Ignore this event unless a provider plugin has requested it. */
+       if (!zdplane_info.dg_sys_route_notifs) {
+               ret = ZEBRA_DPLANE_REQUEST_SUCCESS;
+               goto done;
+       }
+
+       if (rn == NULL || re == NULL)
+               goto done;
+
+       ret = dplane_route_update_internal(rn, re, NULL,
+                                          DPLANE_OP_SYS_ROUTE_ADD);
+
+done:
+       return ret;
+}
+
+/*
+ * Notify the dplane when system/connected routes are deleted.
+ */
+enum zebra_dplane_result dplane_sys_route_del(struct route_node *rn,
+                                             struct route_entry *re)
+{
+       enum zebra_dplane_result ret = ZEBRA_DPLANE_REQUEST_FAILURE;
+
+       /* Ignore this event unless a provider plugin has requested it. */
+       if (!zdplane_info.dg_sys_route_notifs) {
+               ret = ZEBRA_DPLANE_REQUEST_SUCCESS;
+               goto done;
+       }
+
+       if (rn == NULL || re == NULL)
+               goto done;
+
+       ret = dplane_route_update_internal(rn, re, NULL,
+                                          DPLANE_OP_SYS_ROUTE_DELETE);
+
+done:
+       return ret;
+}
+
 /*
  * Enqueue LSP add for the dataplane.
  */
@@ -1856,6 +1925,12 @@ static int kernel_dplane_process_func(struct zebra_dplane_provider *prov)
                        res = kernel_dplane_pw_update(ctx);
                        break;
 
+               /* Ignore system 'notifications' - the kernel already knows */
+               case DPLANE_OP_SYS_ROUTE_ADD:
+               case DPLANE_OP_SYS_ROUTE_DELETE:
+                       res = ZEBRA_DPLANE_REQUEST_SUCCESS;
+                       break;
+
                default:
                        atomic_fetch_add_explicit(
                                &zdplane_info.dg_other_errors, 1,
@@ -1916,6 +1991,11 @@ static int test_dplane_process_func(struct zebra_dplane_provider *prov)
                if (ctx == NULL)
                        break;
 
+               if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
+                       zlog_debug("dplane provider '%s': op %s",
+                                  dplane_provider_get_name(prov),
+                                  dplane_op2str(dplane_ctx_get_op(ctx)));
+
                dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_SUCCESS);
 
                dplane_provider_enqueue_out_ctx(prov, ctx);
index 1246fcc8ec1d9d25920b4d0d5afd197b0f008463..4e089bc66b7d04bdd9e39645310d1c734ac25994 100644 (file)
@@ -114,8 +114,15 @@ enum dplane_op_e {
        /* Pseudowire update */
        DPLANE_OP_PW_INSTALL,
        DPLANE_OP_PW_UNINSTALL,
+
+       /* System route notification */
+       DPLANE_OP_SYS_ROUTE_ADD,
+       DPLANE_OP_SYS_ROUTE_DELETE,
 };
 
+/* Enable system route notifications */
+void dplane_enable_sys_route_notifs(void);
+
 /*
  * The dataplane context struct is used to exchange info between the main zebra
  * context and the dataplane module(s). If these are two independent pthreads,
@@ -249,6 +256,12 @@ enum zebra_dplane_result dplane_route_update(struct route_node *rn,
 enum zebra_dplane_result dplane_route_delete(struct route_node *rn,
                                             struct route_entry *re);
 
+/* Notify the dplane when system/connected routes change */
+enum zebra_dplane_result dplane_sys_route_add(struct route_node *rn,
+                                             struct route_entry *re);
+enum zebra_dplane_result dplane_sys_route_del(struct route_node *rn,
+                                             struct route_entry *re);
+
 /*
  * Enqueue LSP change operations for the dataplane.
  */
index 9f57e15882fe0361f261dfadf3eb691deb99f11f..e47499b0656deae821692861baa5f0b954f647fb 100644 (file)
@@ -2799,6 +2799,12 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
                        break;
        }
 
+       /* If this route is kernel/connected route, notify the dataplane. */
+       if (RIB_SYSTEM_ROUTE(re)) {
+               /* Notify dataplane */
+               dplane_sys_route_add(rn, re);
+       }
+
        /* Link new re to node.*/
        if (IS_ZEBRA_DEBUG_RIB) {
                rnode_debug(rn, re->vrf_id,
@@ -3010,6 +3016,11 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                                                               &vtep_ip, p);
                        }
                }
+
+               /* Notify dplane if system route changes */
+               if (RIB_SYSTEM_ROUTE(re))
+                       dplane_sys_route_del(rn, same);
+
                rib_delnode(rn, same);
        }
 
@@ -3355,6 +3366,12 @@ static int rib_process_dplane_results(struct thread *thread)
                                handle_pw_result(ctx);
                                break;
 
+                       case DPLANE_OP_SYS_ROUTE_ADD:
+                       case DPLANE_OP_SYS_ROUTE_DELETE:
+                               /* No further processing in zebra for these. */
+                               dplane_ctx_fini(&ctx);
+                               break;
+
                        default:
                                /* Don't expect this: just return the struct? */
                                dplane_ctx_fini(&ctx);