]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgp, zebra: add family attribute to ipset and iptable context
authorPhilippe Guibert <philippe.guibert@6wind.com>
Wed, 16 Oct 2019 09:07:41 +0000 (11:07 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 21 Aug 2020 11:37:08 +0000 (13:37 +0200)
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>
bgpd/bgp_pbr.c
bgpd/bgp_pbr.h
bgpd/bgp_zebra.c
zebra/zapi_msg.c
zebra/zebra_pbr.c
zebra/zebra_pbr.h

index 9446575611051df8314e0bf0be60c927c8135a53..69c19fa7d8daa2b57510b9e0e0f59080a3123002 100644 (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)
index ff333d2f109a42f329557e7b30882be626553d99..9d6360094ca3b4b6e025812585f02ac7edbdb05d 100644 (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;
index bf32d493bc4eaf0d5da72200a0af255be7104fe8..73ce9907243d7b9ab464f4df1cfc8eb6e0e241fa 100644 (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. */
index 2bcb3502d509e64c901d83e57bb8ab5fc9e74e9d..5068765d2fa3c368e68d68ec8f7d0904c20eceb4 100644 (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);
 
index 1bc8d893bcecb7a293e835cbed2610547a0bbc9b..166689385c82a2a1b50a3cea96f51be0f3cb12f8 100644 (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];
 
index 888d2fcfa0c33ced7941639be9e223bd27b452bc..c84e603723e51dad74437c09a8f671a82cfa08fb 100644 (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;