summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_pbr.c7
-rw-r--r--bgpd/bgp_pbr.h1
-rw-r--r--bgpd/bgp_zebra.c4
-rw-r--r--zebra/zapi_msg.c3
-rw-r--r--zebra/zebra_pbr.c34
-rw-r--r--zebra/zebra_pbr.h6
6 files changed, 47 insertions, 8 deletions
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index 9446575611..69c19fa7d8 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -1057,6 +1057,7 @@ uint32_t bgp_pbr_match_hash_key(const void *arg)
key = jhash_1word(pbm->vrf_id, 0x4312abde);
key = jhash_1word(pbm->flags, key);
+ key = jhash_1word(pbm->family, key);
key = jhash(&pbm->pkt_len_min, 2, key);
key = jhash(&pbm->pkt_len_max, 2, key);
key = jhash(&pbm->tcp_flags, 2, key);
@@ -1078,6 +1079,9 @@ bool bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
if (r1->vrf_id != r2->vrf_id)
return false;
+ if (r1->family != r2->family)
+ return false;
+
if (r1->type != r2->type)
return false;
@@ -1762,6 +1766,7 @@ static int bgp_pbr_get_remaining_entry(struct hash_bucket *bucket, void *arg)
bpm_temp->pkt_len_max != bpm->pkt_len_max ||
bpm_temp->dscp_value != bpm->dscp_value ||
bpm_temp->flow_label != bpm->flow_label ||
+ bpm_temp->family != bpm->family ||
bpm_temp->fragment != bpm->fragment)
return HASHWALK_CONTINUE;
@@ -1833,6 +1838,7 @@ static void bgp_pbr_policyroute_remove_from_zebra_unit(
return;
}
+ temp.family = bpf->family;
if (bpf->src) {
temp.flags |= MATCH_IP_SRC_SET;
prefix_copy(&temp2.src, bpf->src);
@@ -2329,6 +2335,7 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
/* then look for bpm */
memset(&temp, 0, sizeof(temp));
temp.vrf_id = bpf->vrf_id;
+ temp.family = bpf->family;
if (bpf->src)
temp.flags |= MATCH_IP_SRC_SET;
if (bpf->dst)
diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h
index ff333d2f10..9d6360094c 100644
--- a/bgpd/bgp_pbr.h
+++ b/bgpd/bgp_pbr.h
@@ -184,6 +184,7 @@ struct bgp_pbr_match {
uint32_t type;
uint32_t flags;
+ uint8_t family;
uint16_t pkt_len_min;
uint16_t pkt_len_max;
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index bf32d493bc..73ce990724 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -2415,7 +2415,7 @@ static void bgp_encode_pbr_ipset_match(struct stream *s,
{
stream_putl(s, pbim->unique);
stream_putl(s, pbim->type);
-
+ stream_putc(s, pbim->family);
stream_put(s, pbim->ipset_name,
ZEBRA_IPSET_NAME_SIZE);
}
@@ -2464,6 +2464,7 @@ static void bgp_encode_pbr_iptable_match(struct stream *s,
stream_putl(s, bpa->fwmark);
stream_put(s, pbm->ipset_name,
ZEBRA_IPSET_NAME_SIZE);
+ stream_putc(s, pbm->family);
stream_putw(s, pbm->pkt_len_min);
stream_putw(s, pbm->pkt_len_max);
stream_putw(s, pbm->tcp_flags);
@@ -2471,6 +2472,7 @@ static void bgp_encode_pbr_iptable_match(struct stream *s,
stream_putc(s, pbm->dscp_value);
stream_putc(s, pbm->fragment);
stream_putc(s, pbm->protocol);
+ stream_putw(s, pbm->flow_label);
}
/* BGP has established connection with Zebra. */
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 2bcb3502d5..5068765d2f 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -2841,6 +2841,7 @@ static inline void zread_ipset(ZAPI_HANDLER_ARGS)
zpi.vrf_id = zvrf->vrf->vrf_id;
STREAM_GETL(s, zpi.unique);
STREAM_GETL(s, zpi.type);
+ STREAM_GETC(s, zpi.family);
STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
if (hdr->command == ZEBRA_IPSET_CREATE)
@@ -2951,6 +2952,7 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS)
STREAM_GETL(s, zpi->action);
STREAM_GETL(s, zpi->fwmark);
STREAM_GET(&zpi->ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
+ STREAM_GETC(s, zpi->family);
STREAM_GETW(s, zpi->pkt_len_min);
STREAM_GETW(s, zpi->pkt_len_max);
STREAM_GETW(s, zpi->tcp_flags);
@@ -2958,6 +2960,7 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS)
STREAM_GETC(s, zpi->dscp_value);
STREAM_GETC(s, zpi->fragment);
STREAM_GETC(s, zpi->protocol);
+ STREAM_GETW(s, zpi->flow_label);
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 1bc8d893bc..166689385c 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -251,6 +251,8 @@ uint32_t zebra_pbr_ipset_hash_key(const void *arg)
uint32_t *pnt = (uint32_t *)&ipset->ipset_name;
uint32_t key = jhash_1word(ipset->vrf_id, 0x63ab42de);
+ key = jhash_1word(ipset->family, key);
+
return jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE, key);
}
@@ -267,6 +269,8 @@ bool zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2)
return false;
if (r1->vrf_id != r2->vrf_id)
return false;
+ if (r1->family != r2->family)
+ return false;
if (strncmp(r1->ipset_name, r2->ipset_name,
ZEBRA_IPSET_NAME_SIZE))
@@ -376,6 +380,8 @@ uint32_t zebra_pbr_iptable_hash_key(const void *arg)
key = jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE,
0x63ab42de);
key = jhash_1word(iptable->fwmark, key);
+ key = jhash_1word(iptable->family, key);
+ key = jhash_1word(iptable->flow_label, key);
key = jhash_1word(iptable->pkt_len_min, key);
key = jhash_1word(iptable->pkt_len_max, key);
key = jhash_1word(iptable->tcp_flags, key);
@@ -411,6 +417,10 @@ bool zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2)
if (strncmp(r1->ipset_name, r2->ipset_name,
ZEBRA_IPSET_NAME_SIZE))
return false;
+ if (r1->family != r2->family)
+ return false;
+ if (r1->flow_label != r2->flow_label)
+ return false;
if (r1->pkt_len_min != r2->pkt_len_min)
return false;
if (r1->pkt_len_max != r2->pkt_len_max)
@@ -876,7 +886,8 @@ static const char *zebra_pbr_prefix2str(union prefixconstptr pu,
const struct prefix *p = pu.p;
char buf[PREFIX2STR_BUFFER];
- if (p->family == AF_INET && p->prefixlen == IPV4_MAX_PREFIXLEN) {
+ if ((p->family == AF_INET && p->prefixlen == IPV4_MAX_PREFIXLEN) ||
+ (p->family == AF_INET6 && p->prefixlen == IPV6_MAX_PREFIXLEN)) {
snprintf(str, size, "%s", inet_ntop(p->family, &p->u.prefix,
buf, PREFIX2STR_BUFFER));
return str;
@@ -1012,8 +1023,9 @@ static int zebra_pbr_show_ipset_walkcb(struct hash_bucket *bucket, void *arg)
struct vty *vty = uniqueipset->vty;
struct zebra_ns *zns = uniqueipset->zns;
- vty_out(vty, "IPset %s type %s\n", zpi->ipset_name,
- zebra_pbr_ipset_type2str(zpi->type));
+ vty_out(vty, "IPset %s type %s family %s\n", zpi->ipset_name,
+ zebra_pbr_ipset_type2str(zpi->type),
+ zpi->family == AF_INET ? "AF_INET" : "AF_INET6");
unique.vty = vty;
unique.zpi = zpi;
unique.zns = zns;
@@ -1058,9 +1070,9 @@ void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname)
vty_out(vty, "No IPset %s found\n", ipsetname);
return;
}
- vty_out(vty, "IPset %s type %s\n", ipsetname,
- zebra_pbr_ipset_type2str(zpi->type));
-
+ vty_out(vty, "IPset %s type %s family %s\n", ipsetname,
+ zebra_pbr_ipset_type2str(zpi->type),
+ zpi->family == AF_INET ? "AF_INET" : "AF_INET6");
unique.vty = vty;
unique.zpi = zpi;
unique.zns = zns;
@@ -1101,7 +1113,9 @@ static void zebra_pbr_show_iptable_unit(struct zebra_pbr_iptable *iptable,
int ret;
uint64_t pkts = 0, bytes = 0;
- vty_out(vty, "IPtable %s action %s (%u)\n", iptable->ipset_name,
+ vty_out(vty, "IPtable %s family %s action %s (%u)\n",
+ iptable->ipset_name,
+ iptable->family == AF_INET ? "AF_INET" : "AF_INET6",
iptable->action == ZEBRA_IPTABLES_DROP ? "drop" : "redirect",
iptable->unique);
if (iptable->type == IPSET_NET_PORT ||
@@ -1140,6 +1154,12 @@ static void zebra_pbr_show_iptable_unit(struct zebra_pbr_iptable *iptable,
iptable->filter_bm & MATCH_DSCP_INVERSE_SET ?
"not" : "", iptable->dscp_value);
}
+ if (iptable->filter_bm & (MATCH_FLOW_LABEL_SET |
+ MATCH_FLOW_LABEL_INVERSE_SET)) {
+ vty_out(vty, "\t flowlabel %s %d\n",
+ iptable->filter_bm & MATCH_FLOW_LABEL_INVERSE_SET ?
+ "not" : "", iptable->flow_label);
+ }
if (iptable->fragment) {
char val_str[10];
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index 888d2fcfa0..c84e603723 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -79,6 +79,9 @@ struct zebra_pbr_ipset {
* but value is an enum ipset_type
*/
uint32_t type;
+
+ uint8_t family;
+
char ipset_name[ZEBRA_IPSET_NAME_SIZE];
};
@@ -150,6 +153,9 @@ struct zebra_pbr_iptable {
uint8_t protocol;
uint32_t nb_interface;
+ uint16_t flow_label;
+
+ uint8_t family;
struct list *interface_name_list;