From: Patrick McHardy <kaber@xxxxxxxxx> Since the ruleset is ordered, userspace needs to know about NLM_F_APPEND to properly interpret a NEWRULE message. In case of replacement we usually don't send a DELX+NEWX message but a NEWX message with the NLM_F_REPLACE flag. Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx> --- net/netfilter/nf_tables_api.c | 21 ++++++++++----------- 1 Datei geändert, 10 Zeilen hinzugefügt(+), 11 Zeilen entfernt(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index bbd463e..c4e4baa 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1126,7 +1126,7 @@ static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = { }; static int nf_tables_fill_rule_info(struct sk_buff *skb, u32 portid, u32 seq, - int event, int family, + int event, u32 flags, int family, const struct nft_table *table, const struct nft_chain *chain, const struct nft_rule *rule) @@ -1137,7 +1137,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, u32 portid, u32 seq, struct nlattr *list; event |= NFNL_SUBSYS_NFTABLES << 8; - nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), 0); + nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), + flags); if (nlh == NULL) goto nla_put_failure; nlh->nlmsg_flags = portid ? NLM_F_MULTI : 0; @@ -1179,7 +1180,7 @@ static int nf_tables_rule_notify(const struct sk_buff *oskb, const struct nft_table *table, const struct nft_chain *chain, const struct nft_rule *rule, - int event, int family) + int event, u32 flags, int family) { struct sk_buff *skb; u32 portid = NETLINK_CB(oskb).portid; @@ -1197,7 +1198,7 @@ static int nf_tables_rule_notify(const struct sk_buff *oskb, if (skb == NULL) goto err; - err = nf_tables_fill_rule_info(skb, portid, seq, event, + err = nf_tables_fill_rule_info(skb, portid, seq, event, flags, family, table, chain, rule); if (err < 0) { kfree_skb(skb); @@ -1237,7 +1238,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb, sizeof(cb->args) - sizeof(cb->args[0])); if (nf_tables_fill_rule_info(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, - NFT_MSG_NEWRULE, + NFT_MSG_NEWRULE, 0, afi->family, table, chain, rule) < 0) goto done; cont: @@ -1292,7 +1293,7 @@ static int nf_tables_getrule(struct sock *nlsk, struct sk_buff *skb, return -ENOMEM; err = nf_tables_fill_rule_info(skb2, NETLINK_CB(skb).portid, - nlh->nlmsg_seq, NFT_MSG_NEWRULE, + nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0, family, table, chain, rule); if (err < 0) goto err; @@ -1415,9 +1416,6 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, if (nlh->nlmsg_flags & NLM_F_REPLACE) { list_replace_rcu(&old_rule->list, &rule->list); - - nf_tables_rule_notify(skb, nlh, table, chain, old_rule, - NFT_MSG_DELRULE, nfmsg->nfgen_family); nf_tables_rule_destroy(old_rule); } else if (nlh->nlmsg_flags & NLM_F_APPEND) list_add_tail_rcu(&rule->list, &chain->rules); @@ -1425,6 +1423,7 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, list_add_rcu(&rule->list, &chain->rules); nf_tables_rule_notify(skb, nlh, table, chain, rule, NFT_MSG_NEWRULE, + nlh->nlmsg_flags & (NLM_F_APPEND | NLM_F_REPLACE), nfmsg->nfgen_family); return 0; @@ -1470,7 +1469,7 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, list_del_rcu(&rule->list); nf_tables_rule_notify(skb, nlh, table, chain, rule, - NFT_MSG_DELRULE, family); + NFT_MSG_DELRULE, 0, family); nf_tables_rule_destroy(rule); } else { /* Remove all rules in this chain */ @@ -1478,7 +1477,7 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, list_del_rcu(&rule->list); nf_tables_rule_notify(skb, nlh, table, chain, rule, - NFT_MSG_DELRULE, family); + NFT_MSG_DELRULE, 0, family); nf_tables_rule_destroy(rule); } } -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html