diff options
| -rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 84 |
1 files changed, 39 insertions, 45 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 4f9c941335c9..85033344aed2 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -203,25 +203,18 @@ nla_put_failure: | |||
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | static int | 205 | static int |
| 206 | ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct, | 206 | dump_counters(struct sk_buff *skb, u64 pkts, u64 bytes, |
| 207 | enum ip_conntrack_dir dir) | 207 | enum ip_conntrack_dir dir) |
| 208 | { | 208 | { |
| 209 | enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; | 209 | enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; |
| 210 | struct nlattr *nest_count; | 210 | struct nlattr *nest_count; |
| 211 | const struct nf_conn_counter *acct; | ||
| 212 | |||
| 213 | acct = nf_conn_acct_find(ct); | ||
| 214 | if (!acct) | ||
| 215 | return 0; | ||
| 216 | 211 | ||
| 217 | nest_count = nla_nest_start(skb, type | NLA_F_NESTED); | 212 | nest_count = nla_nest_start(skb, type | NLA_F_NESTED); |
| 218 | if (!nest_count) | 213 | if (!nest_count) |
| 219 | goto nla_put_failure; | 214 | goto nla_put_failure; |
| 220 | 215 | ||
| 221 | NLA_PUT_BE64(skb, CTA_COUNTERS_PACKETS, | 216 | NLA_PUT_BE64(skb, CTA_COUNTERS_PACKETS, cpu_to_be64(pkts)); |
| 222 | cpu_to_be64(atomic64_read(&acct[dir].packets))); | 217 | NLA_PUT_BE64(skb, CTA_COUNTERS_BYTES, cpu_to_be64(bytes)); |
| 223 | NLA_PUT_BE64(skb, CTA_COUNTERS_BYTES, | ||
| 224 | cpu_to_be64(atomic64_read(&acct[dir].bytes))); | ||
| 225 | 218 | ||
| 226 | nla_nest_end(skb, nest_count); | 219 | nla_nest_end(skb, nest_count); |
| 227 | 220 | ||
| @@ -232,6 +225,27 @@ nla_put_failure: | |||
| 232 | } | 225 | } |
| 233 | 226 | ||
| 234 | static int | 227 | static int |
| 228 | ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct, | ||
| 229 | enum ip_conntrack_dir dir, int type) | ||
| 230 | { | ||
| 231 | struct nf_conn_counter *acct; | ||
| 232 | u64 pkts, bytes; | ||
| 233 | |||
| 234 | acct = nf_conn_acct_find(ct); | ||
| 235 | if (!acct) | ||
| 236 | return 0; | ||
| 237 | |||
| 238 | if (type == IPCTNL_MSG_CT_GET_CTRZERO) { | ||
| 239 | pkts = atomic64_xchg(&acct[dir].packets, 0); | ||
| 240 | bytes = atomic64_xchg(&acct[dir].bytes, 0); | ||
| 241 | } else { | ||
| 242 | pkts = atomic64_read(&acct[dir].packets); | ||
| 243 | bytes = atomic64_read(&acct[dir].bytes); | ||
| 244 | } | ||
| 245 | return dump_counters(skb, pkts, bytes, dir); | ||
| 246 | } | ||
| 247 | |||
| 248 | static int | ||
| 235 | ctnetlink_dump_timestamp(struct sk_buff *skb, const struct nf_conn *ct) | 249 | ctnetlink_dump_timestamp(struct sk_buff *skb, const struct nf_conn *ct) |
| 236 | { | 250 | { |
| 237 | struct nlattr *nest_count; | 251 | struct nlattr *nest_count; |
| @@ -393,15 +407,15 @@ nla_put_failure: | |||
| 393 | } | 407 | } |
| 394 | 408 | ||
| 395 | static int | 409 | static int |
| 396 | ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, | 410 | ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type, |
| 397 | int event, struct nf_conn *ct) | 411 | struct nf_conn *ct) |
| 398 | { | 412 | { |
| 399 | struct nlmsghdr *nlh; | 413 | struct nlmsghdr *nlh; |
| 400 | struct nfgenmsg *nfmsg; | 414 | struct nfgenmsg *nfmsg; |
| 401 | struct nlattr *nest_parms; | 415 | struct nlattr *nest_parms; |
| 402 | unsigned int flags = pid ? NLM_F_MULTI : 0; | 416 | unsigned int flags = pid ? NLM_F_MULTI : 0, event; |
| 403 | 417 | ||
| 404 | event |= NFNL_SUBSYS_CTNETLINK << 8; | 418 | event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_NEW); |
| 405 | nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags); | 419 | nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags); |
| 406 | if (nlh == NULL) | 420 | if (nlh == NULL) |
| 407 | goto nlmsg_failure; | 421 | goto nlmsg_failure; |
| @@ -430,8 +444,8 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, | |||
| 430 | 444 | ||
| 431 | if (ctnetlink_dump_status(skb, ct) < 0 || | 445 | if (ctnetlink_dump_status(skb, ct) < 0 || |
| 432 | ctnetlink_dump_timeout(skb, ct) < 0 || | 446 | ctnetlink_dump_timeout(skb, ct) < 0 || |
| 433 | ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || | 447 | ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL, type) < 0 || |
| 434 | ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0 || | 448 | ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY, type) < 0 || |
| 435 | ctnetlink_dump_timestamp(skb, ct) < 0 || | 449 | ctnetlink_dump_timestamp(skb, ct) < 0 || |
| 436 | ctnetlink_dump_protoinfo(skb, ct) < 0 || | 450 | ctnetlink_dump_protoinfo(skb, ct) < 0 || |
| 437 | ctnetlink_dump_helpinfo(skb, ct) < 0 || | 451 | ctnetlink_dump_helpinfo(skb, ct) < 0 || |
| @@ -612,8 +626,10 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) | |||
| 612 | goto nla_put_failure; | 626 | goto nla_put_failure; |
| 613 | 627 | ||
| 614 | if (events & (1 << IPCT_DESTROY)) { | 628 | if (events & (1 << IPCT_DESTROY)) { |
| 615 | if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || | 629 | if (ctnetlink_dump_counters(skb, ct, |
| 616 | ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0 || | 630 | IP_CT_DIR_ORIGINAL, type) < 0 || |
| 631 | ctnetlink_dump_counters(skb, ct, | ||
| 632 | IP_CT_DIR_REPLY, type) < 0 || | ||
| 617 | ctnetlink_dump_timestamp(skb, ct) < 0) | 633 | ctnetlink_dump_timestamp(skb, ct) < 0) |
| 618 | goto nla_put_failure; | 634 | goto nla_put_failure; |
| 619 | } else { | 635 | } else { |
| @@ -709,24 +725,13 @@ restart: | |||
| 709 | } | 725 | } |
| 710 | if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, | 726 | if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, |
| 711 | cb->nlh->nlmsg_seq, | 727 | cb->nlh->nlmsg_seq, |
| 712 | IPCTNL_MSG_CT_NEW, ct) < 0) { | 728 | NFNL_MSG_TYPE( |
| 729 | cb->nlh->nlmsg_type), | ||
| 730 | ct) < 0) { | ||
| 713 | nf_conntrack_get(&ct->ct_general); | 731 | nf_conntrack_get(&ct->ct_general); |
| 714 | cb->args[1] = (unsigned long)ct; | 732 | cb->args[1] = (unsigned long)ct; |
| 715 | goto out; | 733 | goto out; |
| 716 | } | 734 | } |
| 717 | |||
| 718 | if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == | ||
| 719 | IPCTNL_MSG_CT_GET_CTRZERO) { | ||
| 720 | struct nf_conn_counter *acct; | ||
| 721 | |||
| 722 | acct = nf_conn_acct_find(ct); | ||
| 723 | if (acct) { | ||
| 724 | atomic64_set(&acct[IP_CT_DIR_ORIGINAL].bytes, 0); | ||
| 725 | atomic64_set(&acct[IP_CT_DIR_ORIGINAL].packets, 0); | ||
| 726 | atomic64_set(&acct[IP_CT_DIR_REPLY].bytes, 0); | ||
| 727 | atomic64_set(&acct[IP_CT_DIR_REPLY].packets, 0); | ||
| 728 | } | ||
| 729 | } | ||
| 730 | } | 735 | } |
| 731 | if (cb->args[1]) { | 736 | if (cb->args[1]) { |
| 732 | cb->args[1] = 0; | 737 | cb->args[1] = 0; |
| @@ -1005,7 +1010,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 1005 | 1010 | ||
| 1006 | rcu_read_lock(); | 1011 | rcu_read_lock(); |
| 1007 | err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, | 1012 | err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, |
| 1008 | IPCTNL_MSG_CT_NEW, ct); | 1013 | NFNL_MSG_TYPE(nlh->nlmsg_type), ct); |
| 1009 | rcu_read_unlock(); | 1014 | rcu_read_unlock(); |
| 1010 | nf_ct_put(ct); | 1015 | nf_ct_put(ct); |
| 1011 | if (err <= 0) | 1016 | if (err <= 0) |
| @@ -1015,17 +1020,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 1015 | if (err < 0) | 1020 | if (err < 0) |
| 1016 | goto out; | 1021 | goto out; |
| 1017 | 1022 | ||
| 1018 | if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO) { | ||
| 1019 | struct nf_conn_counter *acct; | ||
| 1020 | |||
| 1021 | acct = nf_conn_acct_find(ct); | ||
| 1022 | if (acct) { | ||
| 1023 | atomic64_set(&acct[IP_CT_DIR_ORIGINAL].bytes, 0); | ||
| 1024 | atomic64_set(&acct[IP_CT_DIR_ORIGINAL].packets, 0); | ||
| 1025 | atomic64_set(&acct[IP_CT_DIR_REPLY].bytes, 0); | ||
| 1026 | atomic64_set(&acct[IP_CT_DIR_REPLY].packets, 0); | ||
| 1027 | } | ||
| 1028 | } | ||
| 1029 | return 0; | 1023 | return 0; |
| 1030 | 1024 | ||
| 1031 | free: | 1025 | free: |
