summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_pbr.c8
-rw-r--r--bgpd/bgp_pbr.h1
-rw-r--r--bgpd/bgp_zebra.c1
-rw-r--r--lib/pbr.h1
-rw-r--r--zebra/zapi_msg.c1
-rw-r--r--zebra/zebra_pbr.c7
-rw-r--r--zebra/zebra_pbr.h1
7 files changed, 20 insertions, 0 deletions
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index 5eef6ac6cc..8852e46686 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -977,6 +977,7 @@ uint32_t bgp_pbr_match_hash_key(const void *arg)
key = jhash(&pbm->tcp_mask_flags, 2, key);
key = jhash(&pbm->dscp_value, 1, key);
key = jhash(&pbm->fragment, 1, key);
+ key = jhash(&pbm->protocol, 1, key);
return jhash_1word(pbm->type, key);
}
@@ -1016,6 +1017,9 @@ bool bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
if (r1->fragment != r2->fragment)
return false;
+
+ if (r1->protocol != r2->protocol)
+ return false;
return true;
}
@@ -2162,6 +2166,10 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
temp.flags |= MATCH_FRAGMENT_INVERSE_SET;
temp.fragment = bpf->fragment->val;
}
+ if (bpf->protocol) {
+ temp.protocol = bpf->protocol;
+ temp.flags |= MATCH_PROTOCOL_SET;
+ }
temp.action = bpa;
bpm = hash_get(bgp->pbr_match_hash, &temp,
bgp_pbr_match_alloc_intern);
diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h
index b368d8892d..393b08da48 100644
--- a/bgpd/bgp_pbr.h
+++ b/bgpd/bgp_pbr.h
@@ -186,6 +186,7 @@ struct bgp_pbr_match {
uint16_t tcp_mask_flags;
uint8_t dscp_value;
uint8_t fragment;
+ uint8_t protocol;
vrf_id_t vrf_id;
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index c0f2dfca17..71f7f6d0e3 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -2436,6 +2436,7 @@ static void bgp_encode_pbr_iptable_match(struct stream *s,
stream_putw(s, pbm->tcp_mask_flags);
stream_putc(s, pbm->dscp_value);
stream_putc(s, pbm->fragment);
+ stream_putc(s, pbm->protocol);
}
/* BGP has established connection with Zebra. */
diff --git a/lib/pbr.h b/lib/pbr.h
index 1425e679c5..ecd50447e5 100644
--- a/lib/pbr.h
+++ b/lib/pbr.h
@@ -121,6 +121,7 @@ struct pbr_rule {
#define MATCH_PKT_LEN_INVERSE_SET (1 << 8)
#define MATCH_FRAGMENT_INVERSE_SET (1 << 9)
#define MATCH_ICMP_SET (1 << 10)
+#define MATCH_PROTOCOL_SET (1 << 11)
extern int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s,
struct pbr_rule *zrule);
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 61200806ba..9a638f8e7f 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -2432,6 +2432,7 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS)
STREAM_GETW(s, zpi.tcp_mask_flags);
STREAM_GETC(s, zpi.dscp_value);
STREAM_GETC(s, zpi.fragment);
+ STREAM_GETC(s, zpi.protocol);
STREAM_GETL(s, zpi.nb_interface);
zebra_pbr_iptable_update_interfacelist(s, &zpi);
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index a82dd4c24a..f95a4ff950 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -373,6 +373,7 @@ uint32_t zebra_pbr_iptable_hash_key(const void *arg)
key = jhash_1word(iptable->tcp_flags, key);
key = jhash_1word(iptable->tcp_mask_flags, key);
key = jhash_1word(iptable->dscp_value, key);
+ key = jhash_1word(iptable->protocol, key);
key = jhash_1word(iptable->fragment, key);
key = jhash_1word(iptable->vrf_id, key);
@@ -414,6 +415,8 @@ bool zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2)
return false;
if (r1->fragment != r2->fragment)
return false;
+ if (r1->protocol != r2->protocol)
+ return false;
return true;
}
@@ -1095,6 +1098,10 @@ static void zebra_pbr_show_iptable_unit(struct zebra_pbr_iptable *iptable,
" not" : "", lookup_msg(fragment_value_str,
iptable->fragment, val_str));
}
+ if (iptable->protocol) {
+ vty_out(vty, "\t protocol %d\n",
+ iptable->protocol);
+ }
ret = hook_call(zebra_pbr_iptable_get_stat, iptable, &pkts,
&bytes);
if (ret && pkts > 0)
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index cc1cc5acd5..fcc9c5c39a 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -145,6 +145,7 @@ struct zebra_pbr_iptable {
uint16_t tcp_mask_flags;
uint8_t dscp_value;
uint8_t fragment;
+ uint8_t protocol;
uint32_t nb_interface;