Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

route-map on-match goto prefix-list-seqno #5719

Closed

Conversation

eqvinox
Copy link
Contributor

@eqvinox eqvinox commented Jan 22, 2020

This is an alternate approach / "discussion" PR for #5270.

It uses the sequence number from the prefix list as the "goto" target in the route-map. This might be a bit "unconventional", but the change is much less intrusive than #5270 and possibly faster too.

ip prefix-list foo seq 100 permit 192.0.2.0/24
ip prefix-list foo seq 200 permit 10.0.0.0/8

route-map bar permit 10
  match ip address prefix-list foo
  on-match goto prefix-list-seqno

route-map bar permit 100
  description "goto target for 192.0.2.0/24"
  no on-match next

route-map bar permit 200
  description "goto target for 10.0.0.0/8"
  no on-match next

While the concept may be a bit "huh?" to users, I think there is also a benefit in having it be obvious to the user what's happening.

Either way this PR is for discussion / comparing with #5270.

(Downside: due to the way we match prefix lists, all the daemons need a similar "mechanical" change as I've done here for bgpd, but I don't think that's a problem.)

Signed-off-by: David Lamparter <equinox@diac24.net>
Signed-off-by: David Lamparter <equinox@diac24.net>
Signed-off-by: David Lamparter <equinox@diac24.net>
Copy link

@polychaeta polychaeta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution to FRR!

Click for style suggestions

To apply these suggestions:

curl -s https://gist.githubusercontent.com/polychaeta/9e336f6ef559abf0753caad2effdf5b3/raw/c331b8877ba1601f955361010fef8bf90c5884a3/cr_5719_1579703467.diff | git apply

diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 83bad8f56..47705c99a 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -634,9 +634,8 @@ route_match_address_prefix_list(void *rule, afi_t afi,
 		return route_match_prefix_list_flowspec(afi, plist,
 							state->prefix);
 
-	plist_ret = prefix_list_apply_which_prefix(plist, NULL,
-						   &state->plist_seqno,
-						   state->prefix);
+	plist_ret = prefix_list_apply_which_prefix(
+		plist, NULL, &state->plist_seqno, state->prefix);
 	return plist_ret == PREFIX_DENY ? RMAP_NOMATCH : RMAP_MATCH;
 }
 
@@ -657,14 +656,14 @@ static void route_match_ip_address_prefix_list_free(void *rule)
 	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
 }
 
-static const struct route_map_rule_cmd
-		route_match_ip_address_prefix_list_cmd = {
-	"ip address prefix-list",
-	NULL,
-	route_match_ip_address_prefix_list_compile,
-	route_match_ip_address_prefix_list_free,
-	NULL,
-	route_match_ip_address_prefix_list_ext,
+static const struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
+	{
+		"ip address prefix-list",
+		NULL,
+		route_match_ip_address_prefix_list_compile,
+		route_match_ip_address_prefix_list_free,
+		NULL,
+		route_match_ip_address_prefix_list_ext,
 };
 
 /* `match ip next-hop prefix-list PREFIX_LIST' */
@@ -2854,13 +2853,13 @@ static void route_match_ipv6_address_prefix_list_free(void *rule)
 }
 
 static const struct route_map_rule_cmd
-		route_match_ipv6_address_prefix_list_cmd = {
-	"ipv6 address prefix-list",
-	NULL,
-	route_match_ipv6_address_prefix_list_compile,
-	route_match_ipv6_address_prefix_list_free,
-	NULL,
-	route_match_ipv6_address_prefix_list_ext,
+	route_match_ipv6_address_prefix_list_cmd = {
+		"ipv6 address prefix-list",
+		NULL,
+		route_match_ipv6_address_prefix_list_compile,
+		route_match_ipv6_address_prefix_list_free,
+		NULL,
+		route_match_ipv6_address_prefix_list_ext,
 };
 
 /* `match ipv6 next-hop type <TYPE>' */
diff --git a/lib/plist.c b/lib/plist.c
index cf4f2e85a..df3f5a252 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -681,11 +681,10 @@ static int prefix_list_entry_match(struct prefix_list_entry *pentry,
 	return 1;
 }
 
-enum prefix_list_type prefix_list_apply_which_prefix(
-	struct prefix_list *plist,
-	const struct prefix **which,
-	uint32_t *seq,
-	const void *object)
+enum prefix_list_type
+prefix_list_apply_which_prefix(struct prefix_list *plist,
+			       const struct prefix **which, uint32_t *seq,
+			       const void *object)
 {
 	struct prefix_list_entry *pentry, *pbest = NULL;
 
diff --git a/lib/plist.h b/lib/plist.h
index 8f5547f1a..60799db0b 100644
--- a/lib/plist.h
+++ b/lib/plist.h
@@ -66,10 +66,10 @@ extern struct prefix_list *prefix_list_lookup(afi_t, const char *);
  */
 extern enum prefix_list_type
 prefix_list_apply_which_prefix(struct prefix_list *plist,
-			       const struct prefix **which,
-			       uint32_t *seq,
+			       const struct prefix **which, uint32_t *seq,
 			       const void *object);
-#define prefix_list_apply(A, B) prefix_list_apply_which_prefix((A), NULL, NULL, (B))
+#define prefix_list_apply(A, B)                                                \
+	prefix_list_apply_which_prefix((A), NULL, NULL, (B))
 
 extern struct prefix_list *prefix_bgp_orf_lookup(afi_t, const char *);
 extern struct stream *prefix_bgp_orf_entry(struct stream *,
diff --git a/lib/routemap.c b/lib/routemap.c
index aadc2980b..056815988 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -1006,7 +1006,8 @@ static void vty_show_route_map_entry(struct vty *vty, struct route_map *map)
 		if (index->exitpolicy == RMAP_GOTO)
 			vty_out(vty, "    Goto %d\n", index->nextpref);
 		else if (index->exitpolicy == RMAP_GOTO_PLIST)
-			vty_out(vty, "    Goto sequence number from prefix-list\n");
+			vty_out(vty,
+				"    Goto sequence number from prefix-list\n");
 		else if (index->exitpolicy == RMAP_NEXT)
 			vty_out(vty, "    Continue to next entry\n");
 		else if (index->exitpolicy == RMAP_EXIT)
@@ -1628,10 +1629,9 @@ route_map_apply_match(struct route_map_rule_list *match_list,
 				ret = (*match->cmd->func_apply_ext)(
 					match->value, state);
 			else
-				ret = (*match->cmd->func_apply)(match->value,
-								state->prefix,
-								state->type,
-								state->object);
+				ret = (*match->cmd->func_apply)(
+					match->value, state->prefix,
+					state->type, state->object);
 
 			/*
 			 * If the consolidated result of func_apply is:
@@ -3054,12 +3054,11 @@ DEFUN (rmap_onmatch_goto,
 	return CMD_SUCCESS;
 }
 
-DEFUN (rmap_onmatch_goto_plist,
-       rmap_onmatch_goto_plist_cmd,
-       "on-match goto prefix-list-seqno",
-       "Exit policy on matches\n"
-       "Goto Clause number\n"
-       "Use sequence from prefix list entry as goto target\n")
+DEFUN(rmap_onmatch_goto_plist, rmap_onmatch_goto_plist_cmd,
+      "on-match goto prefix-list-seqno",
+      "Exit policy on matches\n"
+      "Goto Clause number\n"
+      "Use sequence from prefix list entry as goto target\n")
 {
 	struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
 
@@ -3326,7 +3325,8 @@ static int route_map_config_write(struct vty *vty)
 				vty_out(vty, " on-match goto %d\n",
 					index->nextpref);
 			if (index->exitpolicy == RMAP_GOTO_PLIST)
-				vty_out(vty, " on-match goto prefix-list-seqno\n");
+				vty_out(vty,
+					" on-match goto prefix-list-seqno\n");
 			if (index->exitpolicy == RMAP_NEXT)
 				vty_out(vty, " on-match next\n");
 
diff --git a/lib/routemap.h b/lib/routemap.h
index 275761cd6..083ede43c 100644
--- a/lib/routemap.h
+++ b/lib/routemap.h
@@ -142,8 +142,8 @@ struct route_map_rule_cmd {
 	void *(*func_get_rmap_rule_key)(void *val);
 
 	/* Extended "apply" function */
-	enum route_map_cmd_result_t (*func_apply_ext)(void *rule,
-						struct route_map_state *state);
+	enum route_map_cmd_result_t (*func_apply_ext)(
+		void *rule, struct route_map_state *state);
 };
 
 /* Route map apply error. */
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 38b3dc95b..e2b486e71 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -219,7 +219,8 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
 			plist = prefix_list_lookup(AFI_IP, rp_info->plist);
 
 			if (prefix_list_apply_which_prefix(plist, &p, NULL,
-					group) == PREFIX_DENY)
+							   group)
+			    == PREFIX_DENY)
 				continue;
 
 			if (!best) {

If you are a new contributor to FRR, please see our contributing guidelines.

@eqvinox
Copy link
Contributor Author

eqvinox commented Jan 22, 2020

Instead of tying this to the sequence number, we could also add a new prefix-list parameter (e.g. tag) and use that:

ip prefix-list foo seq 1234 tag 100 permit 192.0.2.0/24
ip prefix-list foo seq 1235 tag 100 permit 127.0.0.1/32
ip prefix-list foo seq 2345 tag 200 permit 10.0.0.0/8

route-map bar permit 10
  match ip address prefix-list foo
  on-match goto prefix-list-tag

route-map bar permit 100
  description "goto target for 192.0.2.0/24 or 127.0.0.1/32"
  no on-match next

route-map bar permit 200
  description "goto target for 10.0.0.0/8"
  no on-match next

@LabN-CI
Copy link
Collaborator

LabN-CI commented Jan 22, 2020

💚 Basic BGPD CI results: SUCCESS, 0 tests failed

Results table
_ _
Result SUCCESS git merge/5719 fd66bf2
Date 01/22/2020
Start 09:35:36
Finish 10:02:00
Run-Time 26:24
Total 1818
Pass 1818
Fail 0
Valgrind-Errors 0
Valgrind-Loss 0
Details vncregress-2020-01-22-09:35:36.txt
Log autoscript-2020-01-22-09:36:44.log.bz2
Memory 433 433 360

For details, please contact louberger

@NetDEF-CI
Copy link
Collaborator

Continuous Integration Result: SUCCESSFUL

Congratulations, this patch passed basic tests

Tested-by: NetDEF / OpenSourceRouting.org CI System

CI System Testrun URL: https://ci1.netdef.org/browse/FRR-FRRPULLREQ-10516/

This is a comment from an automated CI system.
For questions and feedback in regards to this CI system, please feel free to email
Martin Winter - mwinter (at) opensourcerouting.org.

Warnings Generated during build:

Checkout code: Successful with additional warnings
Report for pim_rp.c | 13 issues
===============================================
< ERROR: strcpy() is error-prone; please use strlcpy()#1263: FILE: /tmp/f1-6598/pim_rp.c:1263:
---
> ERROR: strcpy() is error-prone; please use strlcpy()#1263: FILE: /tmp/f2-6598/pim_rp.c:1263:
114c114
< ERROR: strcpy() is error-prone; please use strlcpy()#1265: FILE: /tmp/f1-6598/pim_rp.c:1265:
---
> ERROR: strcpy() is error-prone; please use strlcpy()#1265: FILE: /tmp/f2-6598/pim_rp.c:1265:
117c117
< ERROR: strcpy() is error-prone; please use strlcpy()#1267: FILE: /tmp/f1-6598/pim_rp.c:1267:
---
> ERROR: strcpy() is error-prone; please use strlcpy()#1267: FILE: /tmp/f2-6598/pim_rp.c:1267:
121c121
< #1391: FILE: /tmp/f1-6598/pim_rp.c:1391:
Report for plist.h | 2 issues
===============================================
< WARNING: line over 80 characters
< #72: FILE: /tmp/f1-6598/plist.h:72:
Report for routemap.c | 6 issues
===============================================
< WARNING: line over 80 characters
< #1009: FILE: /tmp/f1-6598/routemap.c:1009:
< WARNING: Block comments use a trailing */ on a separate line
< #3068: FILE: /tmp/f1-6598/routemap.c:3068:
< WARNING: line over 80 characters
< #3329: FILE: /tmp/f1-6598/routemap.c:3329:

Warnings Generated during build:

Debian 10 amd64 build: Successful with additional warnings

Debian Package lintian failed for Debian 10 amd64 build:
(see full package build log at https://ci1.netdef.org/browse/FRR-FRRPULLREQ-10516/artifact/DEB10BUILD/ErrorLog/log_lintian.txt)

W: frr source: pkg-js-tools-test-is-missing
W: frr source: pkg-js-tools-test-is-missing
W: frr-pythontools: changelog-file-missing-explicit-entry 6.0-2 -> 7.4-dev-20200122-02-gfd66bf206-0 (missing) -> 7.4-dev-20200122-02-gfd66bf206-0~deb10u1
W: frr-rpki-rtrlib: changelog-file-missing-explicit-entry 6.0-2 -> 7.4-dev-20200122-02-gfd66bf206-0 (missing) -> 7.4-dev-20200122-02-gfd66bf206-0~deb10u1
W: frr: changelog-file-missing-explicit-entry 6.0-2 -> 7.4-dev-20200122-02-gfd66bf206-0 (missing) -> 7.4-dev-20200122-02-gfd66bf206-0~deb10u1
W: frr-snmp: changelog-file-missing-explicit-entry 6.0-2 -> 7.4-dev-20200122-02-gfd66bf206-0 (missing) -> 7.4-dev-20200122-02-gfd66bf206-0~deb10u1
W: frr-doc: changelog-file-missing-explicit-entry 6.0-2 -> 7.4-dev-20200122-02-gfd66bf206-0 (missing) -> 7.4-dev-20200122-02-gfd66bf206-0~deb10u1
<TITLE>clang_check</TITLE>

clang_check

@NaveenThanikachalam
Copy link
Contributor

Thanks, David.

  • The problem is where every sequence of a route-map has a different prefix-list in its match clause. route-map on-match goto prefix-list-seqno #5719 approach considers only one prefix-list.

  • route-map on-match goto prefix-list-seqno #5719 suggests what to do when a prefix matches a particular route-map sequence. If a prefix does not match a route-map sequence, the next route-map sequence onwards is still evaluated until the one that matches is found. This sequential processing causes the latency.

  • lib: Optimizing route-maps #5270 however, suggests what to do when a prefix does not match a route-map sequence. Instead of running the prefix through the list of route-map sequences sequentially, the optimisation runs the prefix only through a sub-set of sequences that potentially match the prefix being evaluated.

@riw777
Copy link
Member

riw777 commented Feb 4, 2020

My concern here would be -- what if I use the same set of access lists in a lot of different route maps, but want things evaluated in different orders? I don't know if that would work with this solution...

@qlyoung
Copy link
Member

qlyoung commented Feb 4, 2020

@eqvinox any comments re: the above?

@eqvinox eqvinox closed this Mar 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants