From: Philippe Guibert Date: Tue, 12 Jun 2018 16:32:21 +0000 (+0200) Subject: zebra: handling of policy routing iptable tcpflags X-Git-Tag: frr-6.1-dev~217^2~17 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=dc993e76e3cf4dc9280185fdc06c12fd8dd71c4d;p=matthieu%2Ffrr.git zebra: handling of policy routing iptable tcpflags Signed-off-by: Philippe Guibert --- diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 39667a7f8b..f074141213 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -2940,6 +2940,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); diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 1004337602..12000e7755 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -82,6 +82,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, @@ -362,6 +373,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); } @@ -390,6 +403,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; } @@ -958,6 +975,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) @@ -1031,6 +1068,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) diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index c7e3f0d109..960768e15c 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -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,