From 8877968858a8dd6b7ae096988d57a7511c81733d Mon Sep 17 00:00:00 2001 From: Giuseppe Longo Date: Mon, 10 Feb 2014 16:49:33 +0100 Subject: nft: adds save_matches_and_target This patch permits to save matches and target for ip/ip6/arp/eb family, required for xtables-events. Also, generalizes nft_rule_print_save to be reused for all protocol families. Signed-off-by: Giuseppe Longo Signed-off-by: Pablo Neira Ayuso --- iptables/nft-ipv4.c | 8 +++++--- iptables/nft-ipv6.c | 8 +++++--- iptables/nft-shared.c | 34 ++++++++++++++++++++++++++++++++++ iptables/nft-shared.h | 7 +++++-- iptables/nft.c | 33 +++------------------------------ iptables/nft.h | 2 +- 6 files changed, 53 insertions(+), 39 deletions(-) (limited to 'iptables') diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c index 3aeb8a72..02645a29 100644 --- a/iptables/nft-ipv4.c +++ b/iptables/nft-ipv4.c @@ -309,9 +309,10 @@ static void save_ipv4_addr(char letter, const struct in_addr *addr, mask_to_str(mask)); } -static uint8_t nft_ipv4_save_firewall(const struct iptables_command_state *cs, - unsigned int format) +static void nft_ipv4_save_firewall(const void *data, unsigned int format) { + const struct iptables_command_state *cs = data; + save_firewall_details(cs, cs->fw.ip.invflags, cs->fw.ip.proto, cs->fw.ip.iniface, cs->fw.ip.iniface_mask, cs->fw.ip.outiface, cs->fw.ip.outiface_mask, @@ -328,7 +329,8 @@ static uint8_t nft_ipv4_save_firewall(const struct iptables_command_state *cs, save_ipv4_addr('d', &cs->fw.ip.dst, cs->fw.ip.dmsk.s_addr, cs->fw.ip.invflags & IPT_INV_DSTIP); - return cs->fw.ip.flags; + save_matches_and_target(cs->matches, cs->target, + cs->jumpto, cs->fw.ip.flags, &cs->fw); } static void nft_ipv4_proto_parse(struct iptables_command_state *cs, diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c index f30cec61..7c8b43fc 100644 --- a/iptables/nft-ipv6.c +++ b/iptables/nft-ipv6.c @@ -218,9 +218,10 @@ static void save_ipv6_addr(char letter, const struct in6_addr *addr, printf("%s-%c %s ", invert ? "! " : "", letter, addr_str); } -static uint8_t nft_ipv6_save_firewall(const struct iptables_command_state *cs, - unsigned int format) +static void nft_ipv6_save_firewall(const void *data, unsigned int format) { + const struct iptables_command_state *cs = data; + save_firewall_details(cs, cs->fw6.ipv6.invflags, cs->fw6.ipv6.proto, cs->fw6.ipv6.iniface, cs->fw6.ipv6.iniface_mask, cs->fw6.ipv6.outiface, cs->fw6.ipv6.outiface_mask, @@ -231,7 +232,8 @@ static uint8_t nft_ipv6_save_firewall(const struct iptables_command_state *cs, save_ipv6_addr('d', &cs->fw6.ipv6.dst, cs->fw6.ipv6.invflags & IPT_INV_DSTIP); - return cs->fw6.ipv6.flags; + save_matches_and_target(cs->matches, cs->target, + cs->jumpto, cs->fw6.ipv6.flags, &cs->fw6); } /* These are invalid numbers as upper layer protocol */ diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index d0e28ba9..dce8a34a 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -620,6 +620,40 @@ void save_firewall_details(const struct iptables_command_state *cs, } } +void save_matches_and_target(struct xtables_rule_match *m, + struct xtables_target *target, + const char *jumpto, uint8_t flags, const void *fw) +{ + struct xtables_rule_match *matchp; + + for (matchp = m; matchp; matchp = matchp->next) { + if (matchp->match->alias) { + printf("-m %s", + matchp->match->alias(matchp->match->m)); + } else + printf("-m %s", matchp->match->name); + + if (matchp->match->save != NULL) { + /* cs->fw union makes the trick */ + matchp->match->save(fw, matchp->match->m); + } + printf(" "); + } + + if (target != NULL) { + if (target->alias) { + printf("-j %s", target->alias(target->t)); + } else + printf("-j %s", jumpto); + + if (target->save != NULL) + target->save(fw, target->t); + } else if (strlen(jumpto) > 0) + printf("-%c %s", flags & IPT_F_GOTO ? 'g' : 'j', jumpto); + + printf("\n"); +} + void print_matches_and_target(struct iptables_command_state *cs, unsigned int format) { diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index 1d01ebad..145f19d1 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -49,8 +49,7 @@ struct nft_family_ops { void (*parse_immediate)(const char *jumpto, bool nft_goto, void *data); void (*print_firewall)(struct nft_rule *r, unsigned int num, unsigned int format); - uint8_t (*save_firewall)(const struct iptables_command_state *cs, - unsigned int format); + void (*save_firewall)(const void *data, unsigned int format); void (*proto_parse)(struct iptables_command_state *cs, struct xtables_args *args); void (*post_parse)(int command, struct iptables_command_state *cs, @@ -118,6 +117,10 @@ void save_firewall_details(const struct iptables_command_state *cs, const char *outiface, unsigned const char *outiface_mask, unsigned int format); +void save_matches_and_target(struct xtables_rule_match *m, + struct xtables_target *target, + const char *jumpto, + uint8_t flags, const void *fw); struct nft_family_ops *nft_family_ops_lookup(int family); diff --git a/iptables/nft.c b/iptables/nft.c index fc9db998..515d124a 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -1009,15 +1009,13 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table, } void -nft_rule_print_save(const struct iptables_command_state *cs, +nft_rule_print_save(const void *data, struct nft_rule *r, enum nft_rule_print type, unsigned int format) { const char *chain = nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN); int family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY); - struct xtables_rule_match *matchp; struct nft_family_ops *ops; - int ip_flags = 0; /* print chain name */ switch(type) { @@ -1030,35 +1028,10 @@ nft_rule_print_save(const struct iptables_command_state *cs, } ops = nft_family_ops_lookup(family); - ip_flags = ops->save_firewall(cs, format); - - for (matchp = cs->matches; matchp; matchp = matchp->next) { - if (matchp->match->alias) { - printf("-m %s", - matchp->match->alias(matchp->match->m)); - } else - printf("-m %s", matchp->match->name); - - if (matchp->match->save != NULL) { - /* cs->fw union makes the trick */ - matchp->match->save(&cs->fw, matchp->match->m); - } - printf(" "); - } - if (cs->target != NULL) { - if (cs->target->alias) { - printf("-j %s", cs->target->alias(cs->target->t)); - } else - printf("-j %s", cs->jumpto); + if (ops->save_firewall) + ops->save_firewall(data, format); - if (cs->target->save != NULL) - cs->target->save(&cs->fw, cs->target->t); - } else if (strlen(cs->jumpto) > 0) - printf("-%c %s", ip_flags & IPT_F_GOTO ? 'g' : 'j', - cs->jumpto); - - printf("\n"); } static int nft_chain_list_cb(const struct nlmsghdr *nlh, void *data) diff --git a/iptables/nft.h b/iptables/nft.h index 22af66e2..8670f343 100644 --- a/iptables/nft.h +++ b/iptables/nft.h @@ -114,7 +114,7 @@ enum nft_rule_print { NFT_RULE_DEL, }; -void nft_rule_print_save(const struct iptables_command_state *cs, +void nft_rule_print_save(const void *data, struct nft_rule *r, enum nft_rule_print type, unsigned int format); -- cgit v1.2.3