diff options
47 files changed, 408 insertions, 357 deletions
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 89ed9551ce..455315e40d 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -1345,10 +1345,12 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, json_prefix_info = json_object_new_object(); - json_object_string_add( - json_prefix_info, "prefix", - prefix2str((struct prefix_evpn *)p, buf, - BUFSIZ)); + prefix2str((struct prefix_evpn *)p, buf, + BUFSIZ); + + json_object_string_addf( + json_prefix_info, "prefix", "%pFX", + (struct prefix_evpn *)p); json_object_int_add(json_prefix_info, "prefixLen", p->prefixlen); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index b79fe778ae..f8b09e56bf 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8384,7 +8384,6 @@ static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p, { int len = 0; char buf[BUFSIZ]; - char buf2[BUFSIZ]; if (p->family == AF_INET) { if (!json) { @@ -8395,8 +8394,7 @@ static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p, &p->u.prefix, buf, BUFSIZ)); json_object_int_add(json, "prefixLen", p->prefixlen); - prefix2str(p, buf2, PREFIX_STRLEN); - json_object_string_add(json, "network", buf2); + json_object_string_addf(json, "network", "%pFX", p); json_object_int_add(json, "version", dest->version); } } else if (p->family == AF_ETHERNET) { @@ -8420,8 +8418,7 @@ static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p, &p->u.prefix, buf, BUFSIZ)); json_object_int_add(json, "prefixLen", p->prefixlen); - prefix2str(p, buf2, PREFIX_STRLEN); - json_object_string_add(json, "network", buf2); + json_object_string_addf(json, "network", "%pFX", p); json_object_int_add(json, "version", dest->version); } } @@ -9100,8 +9097,7 @@ void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest, BUFSIZ)); json_object_int_add(json_net, "prefixLen", p->prefixlen); - prefix2str(p, buff, PREFIX_STRLEN); - json_object_string_add(json_net, "network", buff); + json_object_string_addf(json_net, "network", "%pFX", p); } } else route_vty_out_route(dest, p, vty, NULL, wide); @@ -11247,7 +11243,6 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, struct peer *peer; struct listnode *node, *nnode; char buf1[RD_ADDRSTRLEN]; - char prefix_str[BUFSIZ]; int count = 0; int best = 0; int suppress = 0; @@ -11301,8 +11296,7 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, dest->version); } else { - json_object_string_add(json, "prefix", - prefix2str(p, prefix_str, sizeof(prefix_str))); + json_object_string_addf(json, "prefix", "%pFX", p); json_object_int_add(json, "version", dest->version); } diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index b2eb70a9cc..2a1dc1896c 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -725,6 +725,57 @@ static const struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_free }; +/* `match ipv6 next-hop prefix-list PREFIXLIST_NAME' */ +static enum route_map_cmd_result_t +route_match_ipv6_next_hop_prefix_list(void *rule, const struct prefix *prefix, + void *object) +{ + struct prefix_list *plist; + struct bgp_path_info *path; + struct prefix_ipv6 p; + + if (prefix->family == AF_INET6) { + path = object; + p.family = AF_INET6; + p.prefix = path->attr->mp_nexthop_global; + p.prefixlen = IPV6_MAX_BITLEN; + + plist = prefix_list_lookup(AFI_IP6, (char *)rule); + if (!plist) + return RMAP_NOMATCH; + + if (prefix_list_apply(plist, &p) == PREFIX_PERMIT) + return RMAP_MATCH; + + if (path->attr->mp_nexthop_len + == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { + p.prefix = path->attr->mp_nexthop_local; + if (prefix_list_apply(plist, &p) == PREFIX_PERMIT) + return RMAP_MATCH; + } + } + + return RMAP_NOMATCH; +} + +static void *route_match_ipv6_next_hop_prefix_list_compile(const char *arg) +{ + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); +} + +static void route_match_ipv6_next_hop_prefix_list_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +static const struct route_map_rule_cmd + route_match_ipv6_next_hop_prefix_list_cmd = { + "ipv6 next-hop prefix-list", + route_match_ipv6_next_hop_prefix_list, + route_match_ipv6_next_hop_prefix_list_compile, + route_match_ipv6_next_hop_prefix_list_free +}; + /* `match ip next-hop type <blackhole>' */ static enum route_map_cmd_result_t @@ -6189,6 +6240,45 @@ ALIAS_HIDDEN (no_match_ipv6_next_hop_address, "Match IPv6 next-hop address of route\n" "IPv6 address of next hop\n") +DEFUN_YANG (match_ipv6_next_hop_prefix_list, + match_ipv6_next_hop_prefix_list_cmd, + "match ipv6 next-hop prefix-list PREFIXLIST_NAME", + MATCH_STR + IPV6_STR + "Match IPv6 next-hop address of route\n" + "Match entries by prefix-list\n" + "IPv6 prefix-list name\n") +{ + const char *xpath = + "./match-condition[condition='frr-route-map:ipv6-next-hop-prefix-list']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/list-name", xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + argv[argc - 1]->arg); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFUN_YANG (no_match_ipv6_next_hop_prefix_list, + no_match_ipv6_next_hop_prefix_list_cmd, + "no match ipv6 next-hop prefix-list [PREFIXLIST_NAME]", + NO_STR + MATCH_STR + IPV6_STR + "Match IPv6 next-hop address of route\n" + "Match entries by prefix-list\n" + "IPv6 prefix-list name\n") +{ + const char *xpath = + "./match-condition[condition='frr-route-map:ipv6-next-hop-prefix-list']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + DEFPY_YANG (match_ipv4_next_hop, match_ipv4_next_hop_cmd, "match ip next-hop address A.B.C.D", @@ -6566,6 +6656,9 @@ void bgp_route_map_init(void) route_map_match_ipv6_next_hop_type_hook(generic_match_add); route_map_no_match_ipv6_next_hop_type_hook(generic_match_delete); + route_map_match_ipv6_next_hop_prefix_list_hook(generic_match_add); + route_map_no_match_ipv6_next_hop_prefix_list_hook(generic_match_delete); + route_map_match_metric_hook(generic_match_add); route_map_no_match_metric_hook(generic_match_delete); @@ -6749,6 +6842,7 @@ void bgp_route_map_init(void) route_map_install_match(&route_match_ipv6_address_cmd); route_map_install_match(&route_match_ipv6_next_hop_cmd); route_map_install_match(&route_match_ipv6_next_hop_address_cmd); + route_map_install_match(&route_match_ipv6_next_hop_prefix_list_cmd); route_map_install_match(&route_match_ipv4_next_hop_cmd); route_map_install_match(&route_match_ipv6_address_prefix_list_cmd); route_map_install_match(&route_match_ipv6_next_hop_type_cmd); @@ -6759,8 +6853,10 @@ void bgp_route_map_init(void) install_element(RMAP_NODE, &match_ipv6_next_hop_cmd); install_element(RMAP_NODE, &match_ipv6_next_hop_address_cmd); + install_element(RMAP_NODE, &match_ipv6_next_hop_prefix_list_cmd); install_element(RMAP_NODE, &no_match_ipv6_next_hop_cmd); install_element(RMAP_NODE, &no_match_ipv6_next_hop_address_cmd); + install_element(RMAP_NODE, &no_match_ipv6_next_hop_prefix_list_cmd); install_element(RMAP_NODE, &match_ipv6_next_hop_old_cmd); install_element(RMAP_NODE, &no_match_ipv6_next_hop_old_cmd); install_element(RMAP_NODE, &match_ipv4_next_hop_cmd); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 88d84a3c50..29076537dc 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -12363,10 +12363,10 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, p->group, &prefix); if (range) { - prefix2str(range, buf1, sizeof(buf1)); - json_object_string_add( + json_object_string_addf( json_neigh, - "peerSubnetRangeGroup", buf1); + "peerSubnetRangeGroup", "%pFX", + range); } } } else { diff --git a/doc/developer/frr-release-procedure.rst b/doc/developer/frr-release-procedure.rst index 08e3057ae6..7c10e6a8fc 100644 --- a/doc/developer/frr-release-procedure.rst +++ b/doc/developer/frr-release-procedure.rst @@ -6,27 +6,29 @@ FRR Release Procedure ``<version>`` - version to be released, e.g. 7.3 ``origin`` - FRR upstream repository -1. Checkout ``dev/<version>``. +Stage 1 - Preparation +--------------------- + +#. Checkout the existing ``dev/<version>`` branch. .. code-block:: console git checkout dev/<version> -2. Create and push a new branch called ``stable/<version>`` based on the +#. Create and push a new branch called ``stable/<version>`` based on the ``dev/<version>`` branch. .. code-block:: console git checkout -b stable/<version> - git push origin stable/<version>:refs/heads/stable/<version> -3. Remove the development branch called ``dev/<version>`` +#. Remove the development branch called ``dev/<version>`` .. code-block:: console git push origin --delete dev/<version> -4. Update Changelog for Red Hat Packages: +#. Update Changelog for Red Hat Packages: Edit :file:`redhat/frr.spec.in` and look for the ``%changelog`` section: @@ -47,7 +49,7 @@ FRR Release Procedure - Add the changelog text below this entry. -5. Update Changelog for Debian Packages: +#. Update Changelog for Debian Packages: Update :file:`debian/changelog`: @@ -80,104 +82,148 @@ FRR Release Procedure . * Your Changes Here -6. Change main version number: +#. Commit the changes, adding the changelog to the commit message. Follow all + existing commit guidelines. The commit message should be akin to:: + + debian, redhat: updating changelog for new release + +#. Change main version number: + + - Edit :file:`configure.ac` and change version in the ``AC_INIT`` command + to ``<version>`` + + Add and commit this change. This commit should be separate from the commit + containing the changelog. The commit message should be:: + + FRR Release <version> - - Edit :file:`configure.ac` and change version in the ``AC_INIT`` command - to ``<version>`` + The version field should be complete; i.e. for ``8.0.0``, the version should + be ``8.0.0`` and not ``8.0`` or ``8``. -7. Commit the changes, adding the changelog to the commit message. Follow all - existing commit guidelines. -8. Create and submit a GitHub pull request, with the ``HEAD`` set to - ``stable/<version>`` and the base set to the upstream ``master`` branch. - Allow NetDef CI to complete its run and verify that all package builds were - successful. +Stage 2 - Staging +----------------- -9. Create a git tag for the version: +#. Push the stable branch to a new remote branch prefixed with ``rc``:: + + git push origin stable/<version>:rc/version + + This will trigger the NetDEF CI, which serve as a sanity check on the + release branch. Verify that all tests pass and that all package builds are + successful. To do this, go to the NetDEF CI located here: + + https://ci1.netdef.org/browse/FRR-FRR + + In the top left, look for ``rc-<version>`` in the "Plan branch" dropdown. + Select this version. Note that it may take a few minutes for the CI to kick + in on this new branch and appear in the list. + +#. Push the stable branch: .. code-block:: console - git tag -a frr-<version> -m "FRRouting Release <version>" + git push origin stable/<version>:refs/heads/stable/<version> -10. Push the commit and new tag. +#. Create and push a git tag for the version: .. code-block:: console - git push origin stable/<version>:refs/head/stable/<version> + git tag -a frr-<version> -m "FRRouting Release <version>" git push origin frr-<version> -11. Kick off the Release build plan on the CI system for the correct release. - Contact Martin Winter for this step. Ensure all release packages build - successfully. +#. Create a new branch based on ``master``, cherry-pick the commit made earlier + that added the changelogs, and use it to create a PR against ``master``. + This way ``master`` has the latest changelog for the next cycle. + +#. Kick off the "Release" build plan on the CI system for the correct release. + Contact Martin Winter for this step. Ensure all release packages build + successfully. + +#. Kick off the Snapcraft build plan for the release. + + +Stage 3 - Publish +----------------- -12. Kick off the Snapcraft build plan for the release. +#. Upload both the Debian and RPM packages to their respective repositories. -13. Acquire the release RPM binary packages from Martin Winter. +#. Coordinate with the maintainer of FRR's RPM repository to publish the RPM + packages on that repository. Update the repository webpage. Verify that the + instructions on the webpage work and that FRR is installable from the + repository on a Red Hat system. -14. On GitHub, go to the <https://github.com/FRRouting/frr/releases>_ and click - "Draft a new release". Write a release announcement. The release - announcement should follow the template in - ``release-announcement-template.md``, located next to this document. Check - for spelling errors, and optionally (but preferably) have other maintainers - proofread the announcement text. + Current maintainer: *Martin Winter* - Attach **only** the binary RPM packages to the GitHub release using - GitHub's attachment functionality. Do not attach Debian packages. Do not - attach source tarballs - these will be generated and attached by GitHub - automatically. Do not publish the release yet. +#. Coordinate with the maintainer of FRR Debian package to publish the Debian + packages on that repository. Update the repository webpage. Verify that the + instructions on the webpage work and that FRR is installable from the + repository on a Debian system. -15. Contact the current Debian maintainer for FRR to get new Debian packages - built and published on our APT repository at https://deb.frrouting.net/. - Ensure the webpage text is updated. Verify that new packages install - successfully on a vanilla Debian installation using the instructions on the - webpage. + Current maintainer: *Jafar Al-Gharaibeh* -16. Deploy Snapcraft release (after CI system finishes the tests for snapcraft - testplan). +#. Log in to the Read The Docs instance. in the "FRRouting" project, navigate + to the "Overview" tab. Ensure there is a ``stable-<version>`` version listed + and that it is enabled. Go to "Admin" and then "Advanced Settings". Change + "Default version" to the new version. This ensures that the documentation + shown to visitors is that of the latest release by default. -17. Update the Read The Docs instance to being publishing documentation built - off the ``stable/<version>`` branch. Contact Quentin Young for this step. + This step must be performed by someone with administrative access to the + Read the Docs instance. -18. Publish the GitHub release. +#. On GitHub, go to the <https://github.com/FRRouting/frr/releases>_ and click + "Draft a new release". Write a release announcement. The release + announcement should follow the template in + ``release-announcement-template.md``, located next to this document. Check + for spelling errors, and optionally (but preferably) have other maintainers + proofread the announcement text. -19. Clone the ``frr-www`` repository: + Do not attach any packages or source tarballs to the GitHub release. - .. code-block:: console + Publish the release once it is reviewed. - git clone https://github.com/FRRouting/frr-www.git +#. Deploy Snapcraft release. Remember that this will automatically upgrade Snap + users. -20. Add a new release announcement, using a previous announcement as template: + Current maintainer: *Martin Winter* - .. code-block:: console +#. Build and publish the Docker containers. - cp <old-version>-launch.md <version>-launch.md + Current maintainer: *Quentin Young* - Paste the GitHub release announcement text into this document, and **remove - line breaks**. In other words, this:: +#. Clone the ``frr-www`` repository: + + .. code-block:: console + + git clone https://github.com/FRRouting/frr-www.git + +#. Add a new release announcement, using a previous announcement as template: + + .. code-block:: console - This is one continuous - sentence that should be - rendered on one line + cp <old-version>.md <version>.md - Needs to be changed to this:: + Paste the GitHub release announcement text into this document, and **remove + line breaks**. In other words, this:: - This is one continuous sentence that should be rendered on one line + This is one continuous + sentence that should be + rendered on one line - This is very important otherwise the announcement will be unreadable on the - website. + Needs to be changed to this:: - Make sure to add a link to the GitHub releases page at the top. + This is one continuous sentence that should be rendered on one line - Once finished, manually add a new entry into ``index.html`` to link to this - new announcement. Look at past commits to see how to do this. + This is very important otherwise the announcement will be unreadable on the + website. -21. Deploy the updated ``frr-www`` on the frrouting.org web server and verify - that the announcement text is visible. + Make sure to add a link to the GitHub releases page at the top. -22. Send an email to ``announce@lists.frrouting.org``. The text of this email - should include the text from the GitHub release. + Once finished, manually add a new entry into ``index.html`` to link to this + new announcement. Look at past commits to see how to do this. -23. Update masters version of the changelog-auto.in +#. Deploy the updated ``frr-www`` on the frrouting.org web server and verify + that the announcement text is visible. - Take the change data and cut-n-paste the changes into the master version below - the @VERSION@-0 lines. So we have the history of the previous release. +#. Send an email to ``announce@lists.frrouting.org``. The text of this email + should include text as appropriate from the GitHub release and a link to the + GitHub release, Debian repository, and RPM repository. diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst index d99911dc02..01d3501333 100644 --- a/doc/user/routemap.rst +++ b/doc/user/routemap.rst @@ -160,6 +160,10 @@ Route Map Match Command This is a BGP specific match command. Matches the specified `ipv6_addr`. +.. clicmd:: match ipv6 next-hop prefix-list PREFIX_LIST + + Match the next-hop according to the given prefix-list. + .. clicmd:: match as-path AS_PATH Matches the specified `as_path`. diff --git a/lib/plist.c b/lib/plist.c index 0b3de88d9f..d2ddb1d61c 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -1010,7 +1010,6 @@ static void vty_show_prefix_entry(struct vty *vty, json_object *json, afi_t afi, if (json) { json_object *json_entry; - char buf[BUFSIZ]; json_entry = json_object_new_object(); json_object_array_add(json_entries, json_entry); @@ -1021,10 +1020,9 @@ static void vty_show_prefix_entry(struct vty *vty, json_object *json, afi_t afi, json_object_string_add( json_entry, "type", prefix_list_type_str(pentry)); - json_object_string_add( - json_entry, "prefix", - prefix2str(&pentry->prefix, buf, - sizeof(buf))); + json_object_string_addf(json_entry, "prefix", + "%pFX", + &pentry->prefix); if (pentry->ge) json_object_int_add( diff --git a/lib/routemap.c b/lib/routemap.c index c4651f39a4..7f733c8114 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -282,6 +282,22 @@ void route_map_no_match_ipv6_next_hop_type_hook(int (*func)( rmap_match_set_hook.no_match_ipv6_next_hop_type = func; } +/* match ipv6 next-hop prefix-list */ +void route_map_match_ipv6_next_hop_prefix_list_hook(int (*func)( + struct route_map_index *index, const char *command, const char *arg, + route_map_event_t type, char *errmsg, size_t errmsg_len)) +{ + rmap_match_set_hook.match_ipv6_next_hop_prefix_list = func; +} + +/* no match ipv6 next-hop prefix-list */ +void route_map_no_match_ipv6_next_hop_prefix_list_hook(int (*func)( + struct route_map_index *index, const char *command, const char *arg, + route_map_event_t type, char *errmsg, size_t errmsg_len)) +{ + rmap_match_set_hook.no_match_ipv6_next_hop_prefix_list = func; +} + /* match metric */ void route_map_match_metric_hook(int (*func)( struct route_map_index *index, const char *command, diff --git a/lib/routemap.h b/lib/routemap.h index 675f89ba92..6c4916898a 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -252,6 +252,8 @@ DECLARE_QOBJ_TYPE(route_map); (strmatch(C, "frr-route-map:ipv6-prefix-list")) #define IS_MATCH_IPv4_NEXTHOP_PREFIX_LIST(C) \ (strmatch(C, "frr-route-map:ipv4-next-hop-prefix-list")) +#define IS_MATCH_IPv6_NEXTHOP_PREFIX_LIST(C) \ + (strmatch(C, "frr-route-map:ipv6-next-hop-prefix-list")) #define IS_MATCH_IPv4_NEXTHOP_TYPE(C) \ (strmatch(C, "frr-route-map:ipv4-next-hop-type")) #define IS_MATCH_IPv6_NEXTHOP_TYPE(C) \ @@ -617,6 +619,14 @@ extern void route_map_no_match_ipv6_next_hop_type_hook(int (*func)( struct route_map_index *index, const char *command, const char *arg, route_map_event_t type, char *errmsg, size_t errmsg_len)); +/* match ipv6 next-hop prefix-list */ +extern void route_map_match_ipv6_next_hop_prefix_list_hook(int (*func)( + struct route_map_index *index, const char *command, const char *arg, + route_map_event_t type, char *errmsg, size_t errmsg_len)); +/* no match ipv6 next-hop prefix-list */ +extern void route_map_no_match_ipv6_next_hop_prefix_list_hook(int (*func)( + struct route_map_index *index, const char *command, const char *arg, + route_map_event_t type, char *errmsg, size_t errmsg_len)); /* match metric */ extern void route_map_match_metric_hook(int (*func)( struct route_map_index *index, const char *command, @@ -764,6 +774,21 @@ struct route_map_match_set_hooks { route_map_event_t type, char *errmsg, size_t errmsg_len); + /* match ipv6 next hop prefix-list */ + int (*match_ipv6_next_hop_prefix_list)(struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type, + char *errmsg, size_t errmsg_len); + + /* no match ipv6 next-hop prefix-list */ + int (*no_match_ipv6_next_hop_prefix_list)(struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type, + char *errmsg, + size_t errmsg_len); + /* match ip next hop prefix list */ int (*match_ip_next_hop_prefix_list)(struct route_map_index *index, const char *command, diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index e26e3a6d2d..52fcaaba53 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -41,7 +41,7 @@ DEFPY_YANG_NOSH( route_map, route_map_cmd, - "route-map WORD$name <deny|permit>$action (1-65535)$sequence", + "route-map RMAP_NAME$name <deny|permit>$action (1-65535)$sequence", ROUTE_MAP_CMD_STR ROUTE_MAP_OP_CMD_STR ROUTE_MAP_SEQUENCE_CMD_STR) @@ -71,7 +71,7 @@ DEFPY_YANG_NOSH( DEFPY_YANG( no_route_map_all, no_route_map_all_cmd, - "no route-map WORD$name", + "no route-map RMAP_NAME$name", NO_STR ROUTE_MAP_CMD_STR) { @@ -86,7 +86,7 @@ DEFPY_YANG( DEFPY_YANG( no_route_map, no_route_map_cmd, - "no route-map WORD$name <deny|permit>$action (1-65535)$sequence", + "no route-map RMAP_NAME$name <deny|permit>$action (1-65535)$sequence", NO_STR ROUTE_MAP_CMD_STR ROUTE_MAP_OP_CMD_STR @@ -575,6 +575,10 @@ void route_map_condition_show(struct vty *vty, const struct lyd_node *dnode, vty_out(vty, " match ip next-hop prefix-list %s\n", yang_dnode_get_string( dnode, "./rmap-match-condition/list-name")); + } else if (IS_MATCH_IPv6_NEXTHOP_PREFIX_LIST(condition)) { + vty_out(vty, " match ipv6 next-hop prefix-list %s\n", + yang_dnode_get_string( + dnode, "./rmap-match-condition/list-name")); } else if (IS_MATCH_IPv6_ADDRESS_LIST(condition)) { vty_out(vty, " match ipv6 address %s\n", yang_dnode_get_string( @@ -1443,7 +1447,7 @@ void route_map_description_show(struct vty *vty, const struct lyd_node *dnode, DEFPY_YANG( route_map_optimization, route_map_optimization_cmd, - "[no] route-map WORD$name optimization", + "[no] route-map RMAP_NAME$name optimization", NO_STR ROUTE_MAP_CMD_STR "Configure route-map optimization\n") diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c index 7f7bc9f9c4..51b879959f 100644 --- a/lib/routemap_northbound.c +++ b/lib/routemap_northbound.c @@ -622,6 +622,16 @@ static int lib_route_map_entry_match_condition_list_name_modify( rhc->rhc_rmi, "ip next-hop prefix-list", acl, RMAP_EVENT_PLIST_ADDED, args->errmsg, args->errmsg_len); + } else if (IS_MATCH_IPv6_NEXTHOP_PREFIX_LIST(condition)) { + if (rmap_match_set_hook.match_ipv6_next_hop_prefix_list == NULL) + return NB_OK; + rhc->rhc_mhook = + rmap_match_set_hook.no_match_ipv6_next_hop_prefix_list; + rhc->rhc_rule = "ipv6 next-hop prefix-list"; + rhc->rhc_event = RMAP_EVENT_PLIST_DELETED; + rv = rmap_match_set_hook.match_ipv6_next_hop_prefix_list( + rhc->rhc_rmi, "ipv6 next-hop prefix-list", acl, + RMAP_EVENT_PLIST_ADDED, args->errmsg, args->errmsg_len); } else if (IS_MATCH_IPv6_ADDRESS_LIST(condition)) { if (rmap_match_set_hook.match_ipv6_address == NULL) return NB_OK; diff --git a/lib/srv6.c b/lib/srv6.c index ccb94b2f76..aacd30a7af 100644 --- a/lib/srv6.c +++ b/lib/srv6.c @@ -161,12 +161,10 @@ void srv6_locator_chunk_free(struct srv6_locator_chunk *chunk) json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk) { - char str[256]; json_object *jo_root = NULL; jo_root = json_object_new_object(); - prefix2str(&chunk->prefix, str, sizeof(str)); - json_object_string_add(jo_root, "prefix", str); + json_object_string_addf(jo_root, "prefix", "%pFX", &chunk->prefix); json_object_string_add(jo_root, "proto", zebra_route_string(chunk->proto)); @@ -175,7 +173,6 @@ json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk) json_object *srv6_locator_json(const struct srv6_locator *loc) { - char str[256]; struct listnode *node; struct srv6_locator_chunk *chunk; json_object *jo_root = NULL; @@ -188,8 +185,7 @@ json_object *srv6_locator_json(const struct srv6_locator *loc) json_object_string_add(jo_root, "name", loc->name); /* set prefix */ - prefix2str(&loc->prefix, str, sizeof(str)); - json_object_string_add(jo_root, "prefix", str); + json_object_string_addf(jo_root, "prefix", "%pFX", &loc->prefix); /* set function_bits_length */ json_object_int_add(jo_root, "functionBitsLength", diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index b439f947de..cba455cff0 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -1410,7 +1410,6 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, struct ospf6_route *route, *match; struct ospf6_external_info *info; struct prefix prefix_id; - struct route_node *node; char ibuf[16]; struct ospf6_redist *red; @@ -1497,13 +1496,6 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, else ospf6_route_add_nexthop(match, ifindex, NULL); - /* create/update binding in external_id_table */ - prefix_id.family = AF_INET; - prefix_id.prefixlen = IPV4_MAX_BITLEN; - prefix_id.u.prefix4.s_addr = htonl(info->id); - node = route_node_get(ospf6->external_id_table, &prefix_id); - node->info = match; - if (IS_OSPF6_DEBUG_ASBR) { inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf)); @@ -2787,7 +2779,6 @@ static void ospf6_originate_new_aggr_lsa(struct ospf6 *ospf6, struct ospf6_external_aggr_rt *aggr) { struct prefix prefix_id; - struct route_node *node; struct ospf6_lsa *lsa = NULL; if (IS_OSPF6_DEBUG_AGGR) @@ -2796,13 +2787,6 @@ static void ospf6_originate_new_aggr_lsa(struct ospf6 *ospf6, aggr->id = ospf6->external_id++; - /* create/update binding in external_id_table */ - prefix_id.family = AF_INET; - prefix_id.prefixlen = 32; - prefix_id.u.prefix4.s_addr = htonl(aggr->id); - node = route_node_get(ospf6->external_id_table, &prefix_id); - node->info = aggr; - if (IS_OSPF6_DEBUG_AGGR) zlog_debug( "Advertise AS-External Id:%pI4 prefix %pFX metric %u", @@ -3014,8 +2998,6 @@ static void ospf6_aggr_handle_external_info(void *data) struct ospf6_lsa *lsa = NULL; struct ospf6_external_info *info; struct ospf6 *ospf6 = NULL; - struct prefix prefix_id; - struct route_node *node; rt->aggr_route = NULL; @@ -3055,13 +3037,6 @@ static void ospf6_aggr_handle_external_info(void *data) info->id = ospf6->external_id++; rt->path.origin.id = htonl(info->id); - /* create/update binding in external_id_table */ - prefix_id.family = AF_INET; - prefix_id.prefixlen = 32; - prefix_id.u.prefix4.s_addr = htonl(info->id); - node = route_node_get(ospf6->external_id_table, &prefix_id); - node->info = rt; - (void)ospf6_originate_type5_type7_lsas(rt, ospf6); } @@ -3642,7 +3617,6 @@ void ospf6_handle_external_lsa_origination(struct ospf6 *ospf6, struct ospf6_external_aggr_rt *aggr; struct ospf6_external_info *info; struct prefix prefix_id; - struct route_node *node; if (!is_default_prefix(p)) { aggr = ospf6_external_aggr_match(ospf6, @@ -3678,14 +3652,6 @@ void ospf6_handle_external_lsa_origination(struct ospf6 *ospf6, */ if (!info->id) { info->id = ospf6->external_id++; - - /* create/update binding in external_id_table */ - prefix_id.family = AF_INET; - prefix_id.prefixlen = 32; - prefix_id.u.prefix4.s_addr = htonl(info->id); - node = route_node_get(ospf6->external_id_table, &prefix_id); - node->info = rt; - } else { prefix_id.family = AF_INET; prefix_id.prefixlen = 32; diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 6e00bd766f..5fed6dfe17 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -151,24 +151,6 @@ void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa, ospf6_lsa_originate(oi->area->ospf6, lsa); } -void ospf6_remove_id_from_external_id_table(struct ospf6 *ospf6, - uint32_t id) -{ - struct prefix prefix_id; - struct route_node *node; - - /* remove binding in external_id_table */ - prefix_id.family = AF_INET; - prefix_id.prefixlen = 32; - prefix_id.u.prefix4.s_addr = id; - node = route_node_lookup(ospf6->external_id_table, &prefix_id); - assert(node); - node->info = NULL; - route_unlock_node(node); /* to free the lookup lock */ - route_unlock_node(node); /* to free the original lock */ - -} - void ospf6_external_lsa_purge(struct ospf6 *ospf6, struct ospf6_lsa *lsa) { uint32_t id = lsa->header->id; @@ -177,8 +159,6 @@ void ospf6_external_lsa_purge(struct ospf6 *ospf6, struct ospf6_lsa *lsa) ospf6_lsa_purge(lsa); - ospf6_remove_id_from_external_id_table(ospf6, id); - /* Delete the corresponding NSSA LSA */ for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) { lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7), id, diff --git a/ospf6d/ospf6_flood.h b/ospf6d/ospf6_flood.h index 775d0d289d..75f3c065bb 100644 --- a/ospf6d/ospf6_flood.h +++ b/ospf6d/ospf6_flood.h @@ -39,8 +39,6 @@ extern void ospf6_lsa_originate_area(struct ospf6_lsa *lsa, struct ospf6_area *oa); extern void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa, struct ospf6_interface *oi); -void ospf6_remove_id_from_external_id_table(struct ospf6 *ospf6, - uint32_t id); void ospf6_external_lsa_purge(struct ospf6 *ospf6, struct ospf6_lsa *lsa); extern void ospf6_lsa_purge(struct ospf6_lsa *lsa); diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 6c79dcfb71..d0540699fe 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -423,7 +423,6 @@ static struct ospf6 *ospf6_create(const char *name) * 1::1, this happened because of LS ID 0. */ o->external_id = OSPF6_EXT_INIT_LS_ID; - o->external_id_table = route_table_init(); o->write_oi_count = OSPF6_WRITE_INTERFACE_COUNT_DEFAULT; o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH; @@ -515,7 +514,6 @@ void ospf6_delete(struct ospf6 *o) ospf6_route_table_delete(o->brouter_table); ospf6_route_table_delete(o->external_table); - route_table_finish(o->external_id_table); ospf6_distance_reset(o); route_table_finish(o->distance_table); diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index 55cab72307..4cc0923e93 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -136,7 +136,6 @@ struct ospf6 { struct ospf6_route_table *brouter_table; struct ospf6_route_table *external_table; - struct route_table *external_id_table; #define OSPF6_EXT_INIT_LS_ID 1 uint32_t external_id; diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index aaacebca14..e9fb891d7e 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -280,6 +280,19 @@ int ospf_ase_calculate_route(struct ospf *ospf, struct ospf_lsa *lsa) return 0; } + /* Type-5 shouldn't be calculated if it is originated from NSSA ASBR. + * As per RFC 3101, expectation is to receive type-7 lsas from + * NSSA ASBR. Ignore calculation, if the current LSA is type-5 and + * originated ASBR's area is NSSA. + */ + if ((lsa->data->type == OSPF_AS_EXTERNAL_LSA) + && (asbr_route->u.std.external_routing != OSPF_AREA_DEFAULT)) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: Ignore, If type-5 LSA from NSSA area."); + return 0; + } + /* Else, this LSA describes an AS external path to destination N. Examine the forwarding address specified in the AS- external-LSA. This indicates the IP address to which diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 84469160d3..24ea764385 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -5966,7 +5966,6 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self, struct summary_lsa *sl; struct as_external_lsa *asel; struct prefix_ipv4 p; - char buf[PREFIX2STR_BUFFER]; if (lsa != NULL) /* If self option is set, check LSA self flag. */ @@ -6025,10 +6024,9 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self, if (!json_lsa) vty_out(vty, " %pFX", &p); else { - prefix2str(&p, buf, sizeof(buf)); - json_object_string_add(json_lsa, - "summaryAddress", - buf); + json_object_string_addf( + json_lsa, "summaryAddress", + "%pFX", &p); } break; case OSPF_AS_EXTERNAL_LSA: @@ -6050,15 +6048,14 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self, (unsigned long)ntohl( asel->e[0].route_tag)); else { - prefix2str(&p, buf, sizeof(buf)); json_object_string_add( json_lsa, "metricType", IS_EXTERNAL_METRIC( asel->e[0].tos) ? "E2" : "E1"); - json_object_string_add(json_lsa, - "route", buf); + json_object_string_addf( + json_lsa, "route", "%pFX", &p); json_object_int_add( json_lsa, "tag", (unsigned long)ntohl( diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c index dddca1d720..47acfd82a2 100644 --- a/pbrd/pbr_vty.c +++ b/pbrd/pbr_vty.c @@ -917,7 +917,6 @@ static void vty_json_pbrms(json_object *j, struct vty *vty, json_object *jpbrm, *nexthop_group; char *nhg_name = pbrms->nhgrp_name ? pbrms->nhgrp_name : pbrms->internal_nhg_name; - char buf[PREFIX_STRLEN]; char rbuf[64]; jpbrm = json_object_new_object(); @@ -953,13 +952,9 @@ static void vty_json_pbrms(json_object *j, struct vty *vty, json_object_string_add(jpbrm, "vrfName", pbrms->vrf_name); if (pbrms->src) - json_object_string_add( - jpbrm, "matchSrc", - prefix2str(pbrms->src, buf, sizeof(buf))); + json_object_string_addf(jpbrm, "matchSrc", "%pFX", pbrms->src); if (pbrms->dst) - json_object_string_add( - jpbrm, "matchDst", - prefix2str(pbrms->dst, buf, sizeof(buf))); + json_object_string_addf(jpbrm, "matchDst", "%pFX", pbrms->dst); if (pbrms->mark) json_object_int_add(jpbrm, "matchMark", pbrms->mark); if (pbrms->dsfield & PBR_DSFIELD_DSCP) diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 60152f355e..e007bdcc10 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -828,26 +828,6 @@ void pim_if_addr_del_all_igmp(struct interface *ifp) } } -void pim_if_addr_del_all_pim(struct interface *ifp) -{ - struct connected *ifc; - struct listnode *node; - struct listnode *nextnode; - - /* PIM/IGMP enabled ? */ - if (!ifp->info) - return; - - for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) { - struct prefix *p = ifc->address; - - if (p->family != AF_INET) - continue; - - pim_if_addr_del_pim(ifc); - } -} - struct in_addr pim_find_primary_addr(struct interface *ifp) { struct connected *ifc; diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h index 55c278d6e2..d0fd3d5925 100644 --- a/pimd/pim_iface.h +++ b/pimd/pim_iface.h @@ -193,7 +193,6 @@ void pim_if_addr_del(struct connected *ifc, int force_prim_as_any); void pim_if_addr_add_all(struct interface *ifp); void pim_if_addr_del_all(struct interface *ifp); void pim_if_addr_del_all_igmp(struct interface *ifp); -void pim_if_addr_del_all_pim(struct interface *ifp); int pim_if_add_vif(struct interface *ifp, bool ispimreg, bool is_vxlan_term); int pim_if_del_vif(struct interface *ifp); diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 3163f7f548..a17e8e89b2 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -1567,10 +1567,3 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom, if (send_upstream_starg) pim_jp_agg_single_upstream_send(&starup->rpf, starup, true); } - -unsigned int pim_ifchannel_hash_key(const void *arg) -{ - const struct pim_ifchannel *ch = arg; - - return jhash_2words(ch->sg.src.s_addr, ch->sg.grp.s_addr, 0); -} diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h index 52f02a660b..332d40d926 100644 --- a/pimd/pim_ifchannel.h +++ b/pimd/pim_ifchannel.h @@ -160,6 +160,5 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom, int pim_ifchannel_compare(const struct pim_ifchannel *ch1, const struct pim_ifchannel *ch2); -unsigned int pim_ifchannel_hash_key(const void *arg); void delete_on_noinfo(struct pim_ifchannel *ch); #endif /* PIM_IFCHANNEL_H */ diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 68b3af72a7..df773f38d0 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -141,18 +141,6 @@ struct igmp_sock *pim_igmp_sock_lookup_ifaddr(struct list *igmp_sock_list, return NULL; } -struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list, int fd) -{ - struct listnode *sock_node; - struct igmp_sock *igmp; - - for (ALL_LIST_ELEMENTS_RO(igmp_sock_list, sock_node, igmp)) - if (fd == igmp->fd) - return igmp; - - return NULL; -} - static int pim_igmp_other_querier_expire(struct thread *t) { struct igmp_sock *igmp; diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h index dfe986e8f5..1d514086f6 100644 --- a/pimd/pim_igmp.h +++ b/pimd/pim_igmp.h @@ -110,7 +110,6 @@ void pim_igmp_if_fini(struct pim_interface *pim_ifp); struct igmp_sock *pim_igmp_sock_lookup_ifaddr(struct list *igmp_sock_list, struct in_addr ifaddr); -struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list, int fd); struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list, struct in_addr ifaddr, struct interface *ifp, diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 4865b0ed46..702e4d1d76 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -1273,10 +1273,9 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) "prefixList", rp_info->plist); else - json_object_string_add( - json_row, "group", - prefix2str(&rp_info->group, buf, - 48)); + json_object_string_addf( + json_row, "group", "%pFX", + &rp_info->group); json_object_string_add(json_row, "source", source); diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index e59dbba9de..05da3cb7c2 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -803,9 +803,8 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up, if (pim_upstream_is_sg_rpt(up) && up->parent && !I_am_RP(pim, up->sg.grp)) send_xg_jp = true; - else - pim_jp_agg_single_upstream_send(&up->rpf, up, - 0 /* prune */); + + pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */); if (send_xg_jp) { if (PIM_DEBUG_PIM_TRACE_DETAIL) diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 0e0f61d186..311aeda338 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -84,13 +84,6 @@ static int interface_address_delete(ZAPI_CALLBACK_ARGS) static int static_ifp_up(struct interface *ifp) { - if (if_is_vrf(ifp)) { - struct static_vrf *svrf = ifp->vrf->info; - - if (svrf) - static_fixup_vrf_ids(svrf); - } - /* Install any static reliant on this interface coming up */ static_install_intf_nh(ifp); static_ifindex_update(ifp, true); diff --git a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/__init__.py b/tests/topotests/bgp_route_map_match_ipv6_nexthop/__init__.py index e69de29bb2..e69de29bb2 100644 --- a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/__init__.py +++ b/tests/topotests/bgp_route_map_match_ipv6_nexthop/__init__.py diff --git a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/r1/bgpd.conf b/tests/topotests/bgp_route_map_match_ipv6_nexthop/r1/bgpd.conf index 5f35d353f4..c2a49252d6 100644 --- a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/r1/bgpd.conf +++ b/tests/topotests/bgp_route_map_match_ipv6_nexthop/r1/bgpd.conf @@ -3,6 +3,8 @@ ipv6 access-list nh1 permit 2001:db8:1::/64 ipv6 access-list nh2 permit 2001:db8:2::/64 ipv6 access-list nh3 permit 2001:db8:3::/64 ! +ipv6 prefix-list nh4 permit 2001:db8:5::/64 le 128 +! router bgp 65001 bgp router-id 10.10.10.1 no bgp ebgp-requires-policy @@ -24,4 +26,7 @@ route-map r2 permit 30 route-map r2 permit 40 match ipv6 next-hop address 2001:db8:4::1 set community 65002:4 +route-map r2 permit 50 + match ipv6 next-hop prefix-list nh4 + set community 65002:5 ! diff --git a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/r1/zebra.conf b/tests/topotests/bgp_route_map_match_ipv6_nexthop/r1/zebra.conf index 1d4374bd8f..1d4374bd8f 100644 --- a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/r1/zebra.conf +++ b/tests/topotests/bgp_route_map_match_ipv6_nexthop/r1/zebra.conf diff --git a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/r2/bgpd.conf b/tests/topotests/bgp_route_map_match_ipv6_nexthop/r2/bgpd.conf index bca67c5363..19dcf3664b 100644 --- a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/r2/bgpd.conf +++ b/tests/topotests/bgp_route_map_match_ipv6_nexthop/r2/bgpd.conf @@ -13,6 +13,7 @@ ipv6 prefix-list p1 permit 2001:db8:1::1/128 ipv6 prefix-list p2 permit 2001:db8:2::1/128 ipv6 prefix-list p3 permit 2001:db8:3::1/128 ipv6 prefix-list p4 permit 2001:db8:4::1/128 +ipv6 prefix-list p5 permit 2001:db8:5::1/128 ! route-map r1 permit 10 match ipv6 address prefix-list p1 @@ -26,4 +27,7 @@ route-map r1 permit 30 route-map r1 permit 40 match ipv6 address prefix-list p4 set ipv6 next-hop global 2001:db8:4::1 +route-map r1 permit 50 + match ipv6 address prefix-list p5 + set ipv6 next-hop global 2001:db8:5::1 ! diff --git a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/r2/zebra.conf b/tests/topotests/bgp_route_map_match_ipv6_nexthop/r2/zebra.conf index 9039f1dec1..e69345f4f6 100644 --- a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/r2/zebra.conf +++ b/tests/topotests/bgp_route_map_match_ipv6_nexthop/r2/zebra.conf @@ -4,6 +4,7 @@ int lo ipv6 address 2001:db8:2::1/128 ipv6 address 2001:db8:3::1/128 ipv6 address 2001:db8:4::1/128 + ipv6 address 2001:db8:5::1/128 ! int r2-eth0 ip address 2001:db8::2/64 diff --git a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/test_bgp_route_map_match_ipv6_nexthop_access_list.py b/tests/topotests/bgp_route_map_match_ipv6_nexthop/test_bgp_route_map_match_ipv6_nexthop.py index 3efe1eca76..8c86526bf1 100644 --- a/tests/topotests/bgp_route_map_match_ipv6_nexthop_access_list/test_bgp_route_map_match_ipv6_nexthop_access_list.py +++ b/tests/topotests/bgp_route_map_match_ipv6_nexthop/test_bgp_route_map_match_ipv6_nexthop.py @@ -20,7 +20,7 @@ """ Test if we can match BGP prefixes by next-hop which is -specified by an IPv6 Access-list. +specified by an IPv6 Access-list, prefix-list or just an address. """ import os @@ -103,6 +103,11 @@ def test_bgp_route_map_match_ipv6_next_hop_access_list(): "communities": "65002:4", } ], + "2001:db8:5::1/128": [ + { + "communities": "65002:5", + } + ], } return topotest.json_cmp(output, expected) diff --git a/tests/topotests/bgp_route_server_client/r1/bgpd.conf b/tests/topotests/bgp_route_server_client/r1/bgpd.conf index af05e49bfa..d6c83079f7 100644 --- a/tests/topotests/bgp_route_server_client/r1/bgpd.conf +++ b/tests/topotests/bgp_route_server_client/r1/bgpd.conf @@ -3,6 +3,7 @@ router bgp 65001 bgp router-id 10.10.10.1 no bgp ebgp-requires-policy neighbor 2001:db8:1::1 remote-as external + neighbor 2001:db8:1::1 timers 3 10 address-family ipv6 unicast redistribute connected neighbor 2001:db8:1::1 activate diff --git a/tests/topotests/bgp_route_server_client/r2/bgpd.conf b/tests/topotests/bgp_route_server_client/r2/bgpd.conf index 6ad7fdf06c..bdcae4a996 100644 --- a/tests/topotests/bgp_route_server_client/r2/bgpd.conf +++ b/tests/topotests/bgp_route_server_client/r2/bgpd.conf @@ -2,7 +2,9 @@ router bgp 65000 view RS bgp router-id 10.10.10.2 no bgp ebgp-requires-policy neighbor 2001:db8:1::2 remote-as external + neighbor 2001:db8:1::2 timers 3 10 neighbor 2001:db8:3::2 remote-as external + neighbor 2001:db8:3::2 timers 3 10 address-family ipv6 unicast redistribute connected neighbor 2001:db8:1::2 activate diff --git a/tests/topotests/bgp_route_server_client/r3/bgpd.conf b/tests/topotests/bgp_route_server_client/r3/bgpd.conf index ea1f73a5dc..4b565e7b77 100644 --- a/tests/topotests/bgp_route_server_client/r3/bgpd.conf +++ b/tests/topotests/bgp_route_server_client/r3/bgpd.conf @@ -3,6 +3,7 @@ router bgp 65003 bgp router-id 10.10.10.3 no bgp ebgp-requires-policy neighbor 2001:db8:3::1 remote-as external + neighbor 2001:db8:3::1 timers 3 10 address-family ipv6 unicast redistribute connected neighbor 2001:db8:3::1 activate diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py index c425e121af..52872ae1a1 100644 --- a/tests/topotests/lib/ospf.py +++ b/tests/topotests/lib/ospf.py @@ -265,35 +265,6 @@ def __create_ospf_global(tgen, input_dict, router, build, load_config, ospf): cmd = "no {}".format(cmd) config_data.append(cmd) - # area interface information for ospf6d only - if ospf == "ospf6": - area_iface = ospf_data.setdefault("neighbors", {}) - if area_iface: - for neighbor in area_iface: - if "area" in area_iface[neighbor]: - iface = input_dict[router]["links"][neighbor]["interface"] - cmd = "interface {} area {}".format( - iface, area_iface[neighbor]["area"] - ) - if area_iface[neighbor].setdefault("delete", False): - cmd = "no {}".format(cmd) - config_data.append(cmd) - - try: - if "area" in input_dict[router]["links"][neighbor]["ospf6"]: - iface = input_dict[router]["links"][neighbor]["interface"] - cmd = "interface {} area {}".format( - iface, - input_dict[router]["links"][neighbor]["ospf6"]["area"], - ) - if input_dict[router]["links"][neighbor].setdefault( - "delete", False - ): - cmd = "no {}".format(cmd) - config_data.append(cmd) - except KeyError: - pass - # summary information summary_data = ospf_data.setdefault("summary-address", {}) if summary_data: @@ -363,69 +334,6 @@ def __create_ospf_global(tgen, input_dict, router, build, load_config, ospf): return config_data -def create_router_ospf6( - tgen, topo=None, input_dict=None, build=False, load_config=True -): - """ - API to configure ospf on router - - Parameters - ---------- - * `tgen` : Topogen object - * `topo` : json file data - * `input_dict` : Input dict data, required when configuring from testcase - * `build` : Only for initial setup phase this is set as True. - - Usage - ----- - input_dict = { - "r1": { - "ospf6": { - "router_id": "22.22.22.22", - } - } - - Returns - ------- - True or False - """ - logger.debug("Entering lib API: create_router_ospf6()") - result = False - - if topo is None: - topo = tgen.json_topo - - if not input_dict: - input_dict = deepcopy(topo) - else: - topo = topo["routers"] - input_dict = deepcopy(input_dict) - - config_data_dict = {} - - for router in input_dict.keys(): - if "ospf6" not in input_dict[router]: - logger.debug("Router %s: 'ospf6' not present in input_dict", router) - continue - - config_data = __create_ospf_global( - tgen, input_dict, router, build, load_config, "ospf6" - ) - if config_data: - config_data_dict[router] = config_data - - try: - result = create_common_configurations( - tgen, config_data_dict, "ospf6", build, load_config - ) - except InvalidCLIError: - logger.error("create_router_ospf6", exc_info=True) - result = False - - logger.debug("Exiting lib API: create_router_ospf6()") - return result - - def config_ospf_interface( tgen, topo=None, input_dict=None, build=False, load_config=True ): diff --git a/tests/topotests/lib/topojson.py b/tests/topotests/lib/topojson.py index 4f23e1ace0..3ca3353ed3 100644 --- a/tests/topotests/lib/topojson.py +++ b/tests/topotests/lib/topojson.py @@ -40,7 +40,7 @@ from lib.common_config import ( topo_daemons, number_to_column, ) -from lib.ospf import create_router_ospf, create_router_ospf6 +from lib.ospf import create_router_ospf from lib.pim import create_igmp_config, create_pim_config from lib.topolog import logger @@ -334,7 +334,6 @@ def build_config_from_json(tgen, topo=None, save_bkup=True): ("igmp", create_igmp_config), ("bgp", create_router_bgp), ("ospf", create_router_ospf), - ("ospf6", create_router_ospf6), ] ) @@ -353,6 +352,18 @@ def build_config_from_json(tgen, topo=None, save_bkup=True): logger.info("build_config_from_json: failed to configure topology") pytest.exit(1) + logger.info("Built config now clearing ospf neighbors as that router-id might not be what is used") + for ospf in ["ospf", "ospf6"]: + for router in data: + if ospf not in data[router]: + continue + + r = tgen.gears[router] + if ospf == "ospf": + r.vtysh_cmd("clear ip ospf process") + else: + r.vtysh_cmd("clear ipv6 ospf6 process") + def create_tgen_from_json(testfile, json_file=None): """Create a topogen object given a testfile. diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py index b80da41bec..fd17180051 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py @@ -408,7 +408,7 @@ def test_ospf_lan_tc1_p0(request): topo_modify_change_ip = deepcopy(topo) intf_ip = topo_modify_change_ip["routers"]["r0"]["links"]["s1"]["ipv4"] topo_modify_change_ip["routers"]["r0"]["links"]["s1"]["ipv4"] = str( - IPv4Address(frr_unicode(intf_ip.split("/")[0])) + 3 + IPv4Address(frr_unicode(intf_ip.split("/")[0])) + 4 ) + "/{}".format(intf_ip.split("/")[1]) build_config_from_json(tgen, topo_modify_change_ip, save_bkup=False) diff --git a/tests/topotests/ospf_dual_stack/test_ospf_dual_stack.json b/tests/topotests/ospf_dual_stack/test_ospf_dual_stack.json index c8a3ce783b..cdb8813b3d 100644 --- a/tests/topotests/ospf_dual_stack/test_ospf_dual_stack.json +++ b/tests/topotests/ospf_dual_stack/test_ospf_dual_stack.json @@ -23,7 +23,8 @@ }, "ospf6": { "hello_interval": 1, - "dead_interval": 4 + "dead_interval": 4, + "area": "1.1.1.1" } } }, @@ -36,9 +37,7 @@ "ospf6": { "router_id": "1.1.1.1", "neighbors": { - "r3": { - "area": "1.1.1.1" - } + "r3": {} } } }, @@ -56,7 +55,8 @@ "ospf6": { "hello_interval": 1, "dead_interval": 4, - "network": "point-to-point" + "network": "point-to-point", + "area": "1.1.1.1" } }, "r4": { @@ -71,7 +71,8 @@ "ospf6": { "hello_interval": 1, "dead_interval": 4, - "network": "point-to-point" + "network": "point-to-point", + "area": "0.0.0.0" } } }, @@ -85,8 +86,8 @@ "ospf6": { "router_id": "2.2.2.2", "neighbors": { - "r3": { "area": "1.1.1.1" }, - "r4": { "area": "0.0.0.0" } + "r3": {}, + "r4": {} } } }, @@ -104,7 +105,8 @@ "ospf6": { "hello_interval": 1, "dead_interval": 4, - "network": "point-to-point" + "network": "point-to-point", + "area": "1.1.1.1" } }, "r2": { @@ -119,7 +121,8 @@ "ospf6": { "hello_interval": 1, "dead_interval": 4, - "network": "point-to-point" + "network": "point-to-point", + "area": "1.1.1.1" } }, "r4": { @@ -134,7 +137,8 @@ "ospf6": { "hello_interval": 1, "dead_interval": 4, - "network": "point-to-point" + "network": "point-to-point", + "area": "0.0.0.0" } } }, @@ -149,9 +153,9 @@ "ospf6": { "router_id": "3.3.3.3", "neighbors": { - "r1": { "area": "1.1.1.1" }, - "r2": { "area": "1.1.1.1" }, - "r4": { "area": "0.0.0.0" } + "r1": {}, + "r2": {}, + "r4": {} } } }, @@ -169,7 +173,8 @@ "ospf6": { "hello_interval": 1, "dead_interval": 4, - "network": "point-to-point" + "network": "point-to-point", + "area": "0.0.0.0" } }, "r3": { @@ -184,7 +189,8 @@ "ospf6": { "hello_interval": 1, "dead_interval": 4, - "network": "point-to-point" + "network": "point-to-point", + "area": "0.0.0.0" } }, "r5": { @@ -199,7 +205,8 @@ "ospf6": { "hello_interval": 1, "dead_interval": 4, - "network": "point-to-point" + "network": "point-to-point", + "area": "2.2.2.2" } } }, @@ -214,9 +221,9 @@ "ospf6": { "router_id": "4.4.4.4", "neighbors": { - "r2": { "area": "0.0.0.0" }, - "r3": { "area": "0.0.0.0" }, - "r5": { "area": "2.2.2.2" } + "r2": {}, + "r3": {}, + "r5": {} } } }, @@ -234,7 +241,8 @@ "ospf6": { "hello_interval": 1, "dead_interval": 4, - "network": "point-to-point" + "network": "point-to-point", + "area": "2.2.2.2" } } }, @@ -247,7 +255,7 @@ "ospf6": { "router_id": "5.5.5.5", "neighbors": { - "r4": { "area": "2.2.2.2" } + "r4": {} } } } diff --git a/tools/coccinelle/json_object_string_addf.cocci b/tools/coccinelle/json_object_string_addf_inet_ntop.cocci index d9f92e564c..d9f92e564c 100644 --- a/tools/coccinelle/json_object_string_addf.cocci +++ b/tools/coccinelle/json_object_string_addf_inet_ntop.cocci diff --git a/tools/coccinelle/json_object_string_addf_prefix2str.cocci b/tools/coccinelle/json_object_string_addf_prefix2str.cocci new file mode 100644 index 0000000000..ae012b91be --- /dev/null +++ b/tools/coccinelle/json_object_string_addf_prefix2str.cocci @@ -0,0 +1,16 @@ +@@ +identifier json; +expression family, value; +expression prefix; +constant key; +@@ + +( +-prefix2str(prefix, value, ...); +... +-json_object_string_add(json, key, value); ++json_object_string_addf(json, key, "%pFX", prefix); +| +-json_object_string_add(json, key, prefix2str(prefix, value, ...)); ++json_object_string_addf(json, key, "%pFX", prefix); +) diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index b05ad9e3d8..b9577ccd8c 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2146,7 +2146,7 @@ DEFUNSH(VTYSH_PATHD, pcep_cli_pcep_pce_config, pcep_cli_pcep_pce_config_cmd, #endif /* HAVE_PATHD */ DEFUNSH(VTYSH_RMAP, vtysh_route_map, vtysh_route_map_cmd, - "route-map WORD <deny|permit> (1-65535)", + "route-map RMAP_NAME <deny|permit> (1-65535)", "Create route-map or enter route-map command mode\n" "Route map tag\n" "Route map denies set operations\n" diff --git a/yang/frr-route-map.yang b/yang/frr-route-map.yang index fa55a8c7cb..1e8c04bc6f 100644 --- a/yang/frr-route-map.yang +++ b/yang/frr-route-map.yang @@ -112,6 +112,12 @@ module frr-route-map { "Match an IPv6 next-hop"; } + identity ipv6-next-hop-prefix-list { + base rmap-match-type; + description + "Match an IPv6 next-hop prefix list"; + } + identity ipv6-next-hop-type { base rmap-match-type; description @@ -207,6 +213,7 @@ module frr-route-map { + "derived-from-or-self(../condition, 'ipv4-next-hop-prefix-list') or " + "derived-from-or-self(../condition, 'ipv6-address-list') or " + "derived-from-or-self(../condition, 'ipv6-next-hop-list') or " + + "derived-from-or-self(../condition, 'ipv6-next-hop-prefix-list') or " + "derived-from-or-self(../condition, 'ipv6-prefix-list')"; leaf list-name { type filter:access-list-name; diff --git a/zebra/interface.c b/zebra/interface.c index d300397b4e..6ad6e4e3f6 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1310,7 +1310,6 @@ static void connected_dump_vty(struct vty *vty, json_object *json, { struct prefix *p; json_object *json_addr = NULL; - char buf[PREFIX2STR_BUFFER]; /* Print interface address. */ p = connected->address; @@ -1318,8 +1317,7 @@ static void connected_dump_vty(struct vty *vty, json_object *json, if (json) { json_addr = json_object_new_object(); json_object_array_add(json, json_addr); - json_object_string_add(json_addr, "address", - prefix2str(p, buf, sizeof(buf))); + json_object_string_addf(json_addr, "address", "%pFX", p); } else { vty_out(vty, " %s %pFX", prefix_family_str(p), p); } @@ -1327,10 +1325,8 @@ static void connected_dump_vty(struct vty *vty, json_object *json, /* If there is destination address, print it. */ if (CONNECTED_PEER(connected) && connected->destination) { if (json) { - json_object_string_add( - json_addr, "peer", - prefix2str(connected->destination, buf, - sizeof(buf))); + json_object_string_addf(json_addr, "peer", "%pFX", + connected->destination); } else { vty_out(vty, " peer %pFX", connected->destination); } |
