bgp, zebra: add family attribute to ipset and iptable context

in order to create appropriate policy route, family attribute is stored
in ipset and iptable zapi contexts. This commit also adds the flow label
attribute in iptables, for further usage.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2019-10-16 11:07:41 +02:00
parent f01e580fc0
commit a60b7031f9
6 changed files with 47 additions and 8 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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. */

View file

@ -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);

View file

@ -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];

View file

@ -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;