]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: handling of policy routing iptable tcpflags
authorPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 12 Jun 2018 16:32:21 +0000 (18:32 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 2 Jul 2018 07:20:39 +0000 (09:20 +0200)
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
zebra/zapi_msg.c
zebra/zebra_pbr.c
zebra/zebra_pbr.h

index 65cf4ba8be8b6448f8eb4854b9c13ab2805b9318..119476a38285394a20c30cdf94dc55158ea3c23c 100644 (file)
@@ -2908,6 +2908,8 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS)
        STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
        STREAM_GETW(s, zpi.pkt_len_min);
        STREAM_GETW(s, zpi.pkt_len_max);
+       STREAM_GETW(s, zpi.tcp_flags);
+       STREAM_GETW(s, zpi.tcp_mask_flags);
        STREAM_GETL(s, zpi.nb_interface);
        zebra_pbr_iptable_update_interfacelist(s, &zpi);
 
index 07b29bc403994d6c8877e8625e37fc9779982522..ea66689fad92f16f4cd852e70b17569b1d7de174 100644 (file)
@@ -81,6 +81,17 @@ const struct message icmp_typecode_str[] = {
        {0}
 };
 
+/* definitions */
+static const struct message tcp_value_str[] = {
+       {TCP_HEADER_FIN, "FIN"},
+       {TCP_HEADER_SYN, "SYN"},
+       {TCP_HEADER_RST, "RST"},
+       {TCP_HEADER_PSH, "PSH"},
+       {TCP_HEADER_ACK, "ACK"},
+       {TCP_HEADER_URG, "URG"},
+       {0}
+};
+
 /* static function declarations */
 DEFINE_HOOK(zebra_pbr_ipset_entry_wrap_script_get_stat, (struct zebra_ns *zns,
                                    struct zebra_pbr_ipset_entry *ipset,
@@ -361,6 +372,8 @@ uint32_t zebra_pbr_iptable_hash_key(void *arg)
        key = jhash_1word(iptable->fwmark, key);
        key = jhash_1word(iptable->pkt_len_min, key);
        key = jhash_1word(iptable->pkt_len_max, key);
+       key = jhash_1word(iptable->tcp_flags, key);
+       key = jhash_1word(iptable->tcp_mask_flags, key);
        return jhash_3words(iptable->filter_bm, iptable->type,
                            iptable->unique, key);
 }
@@ -389,6 +402,10 @@ int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2)
                return 0;
        if (r1->pkt_len_max != r2->pkt_len_max)
                return 0;
+       if (r1->tcp_flags != r2->tcp_flags)
+               return 0;
+       if (r1->tcp_mask_flags != r2->tcp_mask_flags)
+               return 0;
        return 1;
 }
 
@@ -955,6 +972,26 @@ static int zebra_pbr_show_ipset_walkcb(struct hash_backet *backet, void *arg)
        return HASHWALK_CONTINUE;
 }
 
+size_t zebra_pbr_tcpflags_snprintf(char *buffer, size_t len,
+                                  uint16_t tcp_val)
+{
+       size_t len_written = 0;
+       static struct message nt = {0};
+       const struct message *pnt;
+       int incr = 0;
+
+       for (pnt = tcp_value_str;
+            memcmp(pnt, &nt, sizeof(struct message)); pnt++)
+               if (pnt->key & tcp_val) {
+                       len_written += snprintf(buffer + len_written,
+                                               len - len_written,
+                                               "%s%s", incr ?
+                                               ",":"", pnt->str);
+                       incr++;
+               }
+       return len_written;
+}
+
 /*
  */
 void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname)
@@ -1028,6 +1065,19 @@ static int zebra_pbr_show_iptable_walkcb(struct hash_backet *backet, void *arg)
                                iptable->pkt_len_min,
                                iptable->pkt_len_max);
        }
+       if (iptable->tcp_flags || iptable->tcp_mask_flags) {
+               char tcp_flag_str[64];
+               char tcp_flag_mask_str[64];
+
+               zebra_pbr_tcpflags_snprintf(tcp_flag_str,
+                                           sizeof(tcp_flag_str),
+                                           iptable->tcp_flags);
+               zebra_pbr_tcpflags_snprintf(tcp_flag_mask_str,
+                                           sizeof(tcp_flag_mask_str),
+                                           iptable->tcp_mask_flags);
+               vty_out(vty, "\t tcpflags [%s/%s]\n",
+                       tcp_flag_str, tcp_flag_mask_str);
+       }
        ret = hook_call(zebra_pbr_iptable_wrap_script_get_stat,
                        zns, iptable, &pkts, &bytes);
        if (ret && pkts > 0)
index 09004e795330fed4bde640bee9912ae1cb6f3fa7..8d06aa85949c1a16b7241c05472645cddd5a01a9 100644 (file)
@@ -135,6 +135,8 @@ struct zebra_pbr_iptable {
 
        uint16_t pkt_len_min;
        uint16_t pkt_len_max;
+       uint16_t tcp_flags;
+       uint16_t tcp_mask_flags;
 
        uint32_t nb_interface;
 
@@ -234,6 +236,8 @@ extern void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname);
 extern void zebra_pbr_show_iptable(struct vty *vty);
 extern void zebra_pbr_iptable_update_interfacelist(struct stream *s,
                                   struct zebra_pbr_iptable *zpi);
+size_t zebra_pbr_tcpflags_snprintf(char *buffer, size_t len,
+                                  uint16_t tcp_val);
 
 DECLARE_HOOK(zebra_pbr_ipset_entry_wrap_script_get_stat, (struct zebra_ns *zns,
                                    struct zebra_pbr_ipset_entry *ipset,