summaryrefslogtreecommitdiffstats
path: root/pbrd
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2021-06-04 21:48:16 +0200
committerDonald Sharp <sharpd@nvidia.com>2021-07-08 17:12:47 +0200
commit5e732768f4de955edb7ec48212164e252e9a4590 (patch)
tree96e016974d12cae965e297886f30e2b2c9a12687 /pbrd
parentbgpd, pbrd, zebra: Encode/decode the ip proto from daemons to zebra (diff)
downloadfrr-5e732768f4de955edb7ec48212164e252e9a4590.tar.xz
frr-5e732768f4de955edb7ec48212164e252e9a4590.zip
pbrd: Add `match ip-protocol [tcp|udp]`
Add the `match ip-protocol [tcp|udp]` command to allow pbr to match on tcp or udp streams. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Diffstat (limited to 'pbrd')
-rw-r--r--pbrd/pbr_map.h5
-rw-r--r--pbrd/pbr_vty.c41
-rw-r--r--pbrd/pbr_zebra.c2
3 files changed, 47 insertions, 1 deletions
diff --git a/pbrd/pbr_map.h b/pbrd/pbr_map.h
index 567302477..694b915f4 100644
--- a/pbrd/pbr_map.h
+++ b/pbrd/pbr_map.h
@@ -91,6 +91,11 @@ struct pbr_map_sequence {
uint16_t dst_prt;
/*
+ * The ip protocol we want to match on
+ */
+ uint8_t ip_proto;
+
+ /*
* Our policy Catchers
*/
struct prefix *src;
diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c
index f13ed4d42..730f965cd 100644
--- a/pbrd/pbr_vty.c
+++ b/pbrd/pbr_vty.c
@@ -193,6 +193,32 @@ DEFPY(pbr_map_match_dst, pbr_map_match_dst_cmd,
return CMD_SUCCESS;
}
+DEFPY(pbr_map_match_ip_proto, pbr_map_match_ip_proto_cmd,
+ "[no] match ip-protocol [tcp|udp]$ip_proto",
+ NO_STR
+ "Match the rest of the command\n"
+ "Choose an ip-protocol\n"
+ "Match on tcp flows\n"
+ "Match on udp flows\n")
+{
+ struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ struct protoent *p;
+
+ if (!no) {
+ p = getprotobyname(ip_proto);
+ if (!p) {
+ vty_out(vty, "Unable to convert %s to proto id\n",
+ ip_proto);
+ return CMD_WARNING;
+ }
+
+ pbrms->ip_proto = p->p_proto;
+ } else
+ pbrms->ip_proto = 0;
+
+ return CMD_SUCCESS;
+}
+
DEFPY(pbr_map_match_src_port, pbr_map_match_src_port_cmd,
"[no] match src-port (1-65535)$port",
NO_STR
@@ -718,6 +744,13 @@ static void vty_show_pbrms(struct vty *vty,
pbrms->installed ? "yes" : "no",
pbrms->reason ? rbuf : "Valid");
+ if (pbrms->ip_proto) {
+ struct protoent *p;
+
+ p = getprotobynumber(pbrms->ip_proto);
+ vty_out(vty, " IP Protocol Match: %s\n", p->p_name);
+ }
+
if (pbrms->src)
vty_out(vty, " SRC Match: %pFX\n", pbrms->src);
if (pbrms->dst)
@@ -1128,6 +1161,13 @@ static int pbr_vty_map_config_write_sequence(struct vty *vty,
if (pbrms->dst_prt)
vty_out(vty, " match dst-port %u\n", pbrms->dst_prt);
+ if (pbrms->ip_proto) {
+ struct protoent *p;
+
+ p = getprotobynumber(pbrms->ip_proto);
+ vty_out(vty, " match ip-protocol %s\n", p->p_name);
+ }
+
if (pbrms->dsfield & PBR_DSFIELD_DSCP)
vty_out(vty, " match dscp %u\n",
(pbrms->dsfield & PBR_DSFIELD_DSCP) >> 2);
@@ -1218,6 +1258,7 @@ void pbr_vty_init(void)
install_element(CONFIG_NODE, &pbr_set_table_range_cmd);
install_element(CONFIG_NODE, &no_pbr_set_table_range_cmd);
install_element(INTERFACE_NODE, &pbr_policy_cmd);
+ install_element(PBRMAP_NODE, &pbr_map_match_ip_proto_cmd);
install_element(PBRMAP_NODE, &pbr_map_match_src_port_cmd);
install_element(PBRMAP_NODE, &pbr_map_match_dst_port_cmd);
install_element(PBRMAP_NODE, &pbr_map_match_src_cmd);
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index cf7fc16b3..28def509d 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -534,7 +534,7 @@ static void pbr_encode_pbr_map_sequence(struct stream *s,
stream_putl(s, pbrms->seqno);
stream_putl(s, pbrms->ruleno);
stream_putl(s, pbrms->unique);
- stream_putc(s, 0); /* The ip_proto */
+ stream_putc(s, pbrms->ip_proto); /* The ip_proto */
pbr_encode_pbr_map_sequence_prefix(s, pbrms->src, family);
stream_putw(s, pbrms->src_prt);
pbr_encode_pbr_map_sequence_prefix(s, pbrms->dst, family);