]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgp, zebra, lib: add protocol support for iptables
authorPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 6 Jun 2019 15:31:46 +0000 (17:31 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 8 Jul 2019 06:36:45 +0000 (08:36 +0200)
in addition to support for tcpflags, it is possible to filter on any
protocol. the filtering can then be based with iptables.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_pbr.c
bgpd/bgp_pbr.h
bgpd/bgp_zebra.c
lib/pbr.h
zebra/zapi_msg.c
zebra/zebra_pbr.c
zebra/zebra_pbr.h

index 5eef6ac6ccc36ad7ba6ff4ffd29c093bf27ed835..8852e46686277959d70f1111da5ba10bfd000033 100644 (file)
@@ -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);
index b368d8892def96e76559095a0dc53e71b28016d8..393b08da4819285da0f92111b98635e487b76c80 100644 (file)
@@ -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;
 
index c0f2dfca176c709cb020e70e4957459719c7d679..71f7f6d0e3fb9f0d176aefa8f3d218b35bef6045 100644 (file)
@@ -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. */
index 1425e679c5e5e948a25038499aa721c817a0c274..ecd50447e5cab90151e2f6372b48c6c9f8c449d0 100644 (file)
--- 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);
index 61200806ba84ca81b9077771dd0be3963b51b25e..9a638f8e7f42db737bca14fd47ad7a443072c2dc 100644 (file)
@@ -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);
 
index a82dd4c24a856e0fb1921950b68ef6081d8589c6..f95a4ff950e72738ed3ecc254940ca4a76896417 100644 (file)
@@ -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)
index cc1cc5acd58d127386c008c6f712bb24d4b4ec6b..fcc9c5c39a7a987eb66e7386f91d0f7bb2d3882b 100644 (file)
@@ -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;