diff options
-rw-r--r-- | include/linux/netfilter/xt_NFLOG.h | 2 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_core.h | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 5 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_log.c | 8 | ||||
-rw-r--r-- | net/netfilter/x_tables.c | 199 | ||||
-rw-r--r-- | net/netfilter/xt_recent.c | 2 |
6 files changed, 153 insertions, 65 deletions
diff --git a/include/linux/netfilter/xt_NFLOG.h b/include/linux/netfilter/xt_NFLOG.h index cdcd0ed58f7a..4b36aeb46a10 100644 --- a/include/linux/netfilter/xt_NFLOG.h +++ b/include/linux/netfilter/xt_NFLOG.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define _XT_NFLOG_TARGET | 2 | #define _XT_NFLOG_TARGET |
3 | 3 | ||
4 | #define XT_NFLOG_DEFAULT_GROUP 0x1 | 4 | #define XT_NFLOG_DEFAULT_GROUP 0x1 |
5 | #define XT_NFLOG_DEFAULT_THRESHOLD 1 | 5 | #define XT_NFLOG_DEFAULT_THRESHOLD 0 |
6 | 6 | ||
7 | #define XT_NFLOG_MASK 0x0 | 7 | #define XT_NFLOG_MASK 0x0 |
8 | 8 | ||
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index e78afe7f28e3..c25068e38516 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h | |||
@@ -59,7 +59,7 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb) | |||
59 | struct nf_conn *ct = (struct nf_conn *)skb->nfct; | 59 | struct nf_conn *ct = (struct nf_conn *)skb->nfct; |
60 | int ret = NF_ACCEPT; | 60 | int ret = NF_ACCEPT; |
61 | 61 | ||
62 | if (ct) { | 62 | if (ct && ct != &nf_conntrack_untracked) { |
63 | if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) | 63 | if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) |
64 | ret = __nf_conntrack_confirm(skb); | 64 | ret = __nf_conntrack_confirm(skb); |
65 | nf_ct_deliver_cached_events(ct); | 65 | nf_ct_deliver_cached_events(ct); |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index c323643ffcf9..72dbb6d1a6b3 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -201,8 +201,9 @@ icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, | |||
201 | 201 | ||
202 | if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && | 202 | if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && |
203 | nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { | 203 | nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { |
204 | nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, | 204 | if (LOG_INVALID(net, IPPROTO_ICMPV6)) |
205 | "nf_ct_icmpv6: ICMPv6 checksum failed\n"); | 205 | nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, |
206 | "nf_ct_icmpv6: ICMPv6 checksum failed "); | ||
206 | return -NF_ACCEPT; | 207 | return -NF_ACCEPT; |
207 | } | 208 | } |
208 | 209 | ||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index fa49dc7fe100..c712e9fc6bba 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE | 41 | #define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE |
42 | #define NFULNL_TIMEOUT_DEFAULT HZ /* every second */ | 42 | #define NFULNL_TIMEOUT_DEFAULT 100 /* every second */ |
43 | #define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */ | 43 | #define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */ |
44 | #define NFULNL_COPY_RANGE_MAX 0xFFFF /* max packet size is limited by 16-bit struct nfattr nfa_len field */ | 44 | #define NFULNL_COPY_RANGE_MAX 0xFFFF /* max packet size is limited by 16-bit struct nfattr nfa_len field */ |
45 | 45 | ||
@@ -590,8 +590,10 @@ nfulnl_log_packet(u_int8_t pf, | |||
590 | 590 | ||
591 | qthreshold = inst->qthreshold; | 591 | qthreshold = inst->qthreshold; |
592 | /* per-rule qthreshold overrides per-instance */ | 592 | /* per-rule qthreshold overrides per-instance */ |
593 | if (qthreshold > li->u.ulog.qthreshold) | 593 | if (li->u.ulog.qthreshold) |
594 | qthreshold = li->u.ulog.qthreshold; | 594 | if (qthreshold > li->u.ulog.qthreshold) |
595 | qthreshold = li->u.ulog.qthreshold; | ||
596 | |||
595 | 597 | ||
596 | switch (inst->copy_mode) { | 598 | switch (inst->copy_mode) { |
597 | case NFULNL_COPY_META: | 599 | case NFULNL_COPY_META: |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index bfbf521f6ea5..5baccfa5a0de 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -827,59 +827,143 @@ static const struct file_operations xt_table_ops = { | |||
827 | .release = seq_release_net, | 827 | .release = seq_release_net, |
828 | }; | 828 | }; |
829 | 829 | ||
830 | static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos) | 830 | /* |
831 | * Traverse state for ip{,6}_{tables,matches} for helping crossing | ||
832 | * the multi-AF mutexes. | ||
833 | */ | ||
834 | struct nf_mttg_trav { | ||
835 | struct list_head *head, *curr; | ||
836 | uint8_t class, nfproto; | ||
837 | }; | ||
838 | |||
839 | enum { | ||
840 | MTTG_TRAV_INIT, | ||
841 | MTTG_TRAV_NFP_UNSPEC, | ||
842 | MTTG_TRAV_NFP_SPEC, | ||
843 | MTTG_TRAV_DONE, | ||
844 | }; | ||
845 | |||
846 | static void *xt_mttg_seq_next(struct seq_file *seq, void *v, loff_t *ppos, | ||
847 | bool is_target) | ||
831 | { | 848 | { |
832 | struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; | 849 | static const uint8_t next_class[] = { |
833 | u_int16_t af = (unsigned long)pde->data; | 850 | [MTTG_TRAV_NFP_UNSPEC] = MTTG_TRAV_NFP_SPEC, |
851 | [MTTG_TRAV_NFP_SPEC] = MTTG_TRAV_DONE, | ||
852 | }; | ||
853 | struct nf_mttg_trav *trav = seq->private; | ||
854 | |||
855 | switch (trav->class) { | ||
856 | case MTTG_TRAV_INIT: | ||
857 | trav->class = MTTG_TRAV_NFP_UNSPEC; | ||
858 | mutex_lock(&xt[NFPROTO_UNSPEC].mutex); | ||
859 | trav->head = trav->curr = is_target ? | ||
860 | &xt[NFPROTO_UNSPEC].target : &xt[NFPROTO_UNSPEC].match; | ||
861 | break; | ||
862 | case MTTG_TRAV_NFP_UNSPEC: | ||
863 | trav->curr = trav->curr->next; | ||
864 | if (trav->curr != trav->head) | ||
865 | break; | ||
866 | mutex_unlock(&xt[NFPROTO_UNSPEC].mutex); | ||
867 | mutex_lock(&xt[trav->nfproto].mutex); | ||
868 | trav->head = trav->curr = is_target ? | ||
869 | &xt[trav->nfproto].target : &xt[trav->nfproto].match; | ||
870 | trav->class = next_class[trav->class]; | ||
871 | break; | ||
872 | case MTTG_TRAV_NFP_SPEC: | ||
873 | trav->curr = trav->curr->next; | ||
874 | if (trav->curr != trav->head) | ||
875 | break; | ||
876 | /* fallthru, _stop will unlock */ | ||
877 | default: | ||
878 | return NULL; | ||
879 | } | ||
834 | 880 | ||
835 | mutex_lock(&xt[af].mutex); | 881 | if (ppos != NULL) |
836 | return seq_list_start(&xt[af].match, *pos); | 882 | ++*ppos; |
883 | return trav; | ||
837 | } | 884 | } |
838 | 885 | ||
839 | static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 886 | static void *xt_mttg_seq_start(struct seq_file *seq, loff_t *pos, |
887 | bool is_target) | ||
840 | { | 888 | { |
841 | struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; | 889 | struct nf_mttg_trav *trav = seq->private; |
842 | u_int16_t af = (unsigned long)pde->data; | 890 | unsigned int j; |
843 | 891 | ||
844 | return seq_list_next(v, &xt[af].match, pos); | 892 | trav->class = MTTG_TRAV_INIT; |
893 | for (j = 0; j < *pos; ++j) | ||
894 | if (xt_mttg_seq_next(seq, NULL, NULL, is_target) == NULL) | ||
895 | return NULL; | ||
896 | return trav; | ||
845 | } | 897 | } |
846 | 898 | ||
847 | static void xt_match_seq_stop(struct seq_file *seq, void *v) | 899 | static void xt_mttg_seq_stop(struct seq_file *seq, void *v) |
848 | { | 900 | { |
849 | struct proc_dir_entry *pde = seq->private; | 901 | struct nf_mttg_trav *trav = seq->private; |
850 | u_int16_t af = (unsigned long)pde->data; | 902 | |
903 | switch (trav->class) { | ||
904 | case MTTG_TRAV_NFP_UNSPEC: | ||
905 | mutex_unlock(&xt[NFPROTO_UNSPEC].mutex); | ||
906 | break; | ||
907 | case MTTG_TRAV_NFP_SPEC: | ||
908 | mutex_unlock(&xt[trav->nfproto].mutex); | ||
909 | break; | ||
910 | } | ||
911 | } | ||
851 | 912 | ||
852 | mutex_unlock(&xt[af].mutex); | 913 | static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos) |
914 | { | ||
915 | return xt_mttg_seq_start(seq, pos, false); | ||
853 | } | 916 | } |
854 | 917 | ||
855 | static int xt_match_seq_show(struct seq_file *seq, void *v) | 918 | static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *ppos) |
856 | { | 919 | { |
857 | struct xt_match *match = list_entry(v, struct xt_match, list); | 920 | return xt_mttg_seq_next(seq, v, ppos, false); |
921 | } | ||
858 | 922 | ||
859 | if (strlen(match->name)) | 923 | static int xt_match_seq_show(struct seq_file *seq, void *v) |
860 | return seq_printf(seq, "%s\n", match->name); | 924 | { |
861 | else | 925 | const struct nf_mttg_trav *trav = seq->private; |
862 | return 0; | 926 | const struct xt_match *match; |
927 | |||
928 | switch (trav->class) { | ||
929 | case MTTG_TRAV_NFP_UNSPEC: | ||
930 | case MTTG_TRAV_NFP_SPEC: | ||
931 | if (trav->curr == trav->head) | ||
932 | return 0; | ||
933 | match = list_entry(trav->curr, struct xt_match, list); | ||
934 | return (*match->name == '\0') ? 0 : | ||
935 | seq_printf(seq, "%s\n", match->name); | ||
936 | } | ||
937 | return 0; | ||
863 | } | 938 | } |
864 | 939 | ||
865 | static const struct seq_operations xt_match_seq_ops = { | 940 | static const struct seq_operations xt_match_seq_ops = { |
866 | .start = xt_match_seq_start, | 941 | .start = xt_match_seq_start, |
867 | .next = xt_match_seq_next, | 942 | .next = xt_match_seq_next, |
868 | .stop = xt_match_seq_stop, | 943 | .stop = xt_mttg_seq_stop, |
869 | .show = xt_match_seq_show, | 944 | .show = xt_match_seq_show, |
870 | }; | 945 | }; |
871 | 946 | ||
872 | static int xt_match_open(struct inode *inode, struct file *file) | 947 | static int xt_match_open(struct inode *inode, struct file *file) |
873 | { | 948 | { |
949 | struct seq_file *seq; | ||
950 | struct nf_mttg_trav *trav; | ||
874 | int ret; | 951 | int ret; |
875 | 952 | ||
876 | ret = seq_open(file, &xt_match_seq_ops); | 953 | trav = kmalloc(sizeof(*trav), GFP_KERNEL); |
877 | if (!ret) { | 954 | if (trav == NULL) |
878 | struct seq_file *seq = file->private_data; | 955 | return -ENOMEM; |
879 | 956 | ||
880 | seq->private = PDE(inode); | 957 | ret = seq_open(file, &xt_match_seq_ops); |
958 | if (ret < 0) { | ||
959 | kfree(trav); | ||
960 | return ret; | ||
881 | } | 961 | } |
882 | return ret; | 962 | |
963 | seq = file->private_data; | ||
964 | seq->private = trav; | ||
965 | trav->nfproto = (unsigned long)PDE(inode)->data; | ||
966 | return 0; | ||
883 | } | 967 | } |
884 | 968 | ||
885 | static const struct file_operations xt_match_ops = { | 969 | static const struct file_operations xt_match_ops = { |
@@ -887,62 +971,63 @@ static const struct file_operations xt_match_ops = { | |||
887 | .open = xt_match_open, | 971 | .open = xt_match_open, |
888 | .read = seq_read, | 972 | .read = seq_read, |
889 | .llseek = seq_lseek, | 973 | .llseek = seq_lseek, |
890 | .release = seq_release, | 974 | .release = seq_release_private, |
891 | }; | 975 | }; |
892 | 976 | ||
893 | static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos) | 977 | static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos) |
894 | { | 978 | { |
895 | struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; | 979 | return xt_mttg_seq_start(seq, pos, true); |
896 | u_int16_t af = (unsigned long)pde->data; | ||
897 | |||
898 | mutex_lock(&xt[af].mutex); | ||
899 | return seq_list_start(&xt[af].target, *pos); | ||
900 | } | 980 | } |
901 | 981 | ||
902 | static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 982 | static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *ppos) |
903 | { | 983 | { |
904 | struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; | 984 | return xt_mttg_seq_next(seq, v, ppos, true); |
905 | u_int16_t af = (unsigned long)pde->data; | ||
906 | |||
907 | return seq_list_next(v, &xt[af].target, pos); | ||
908 | } | ||
909 | |||
910 | static void xt_target_seq_stop(struct seq_file *seq, void *v) | ||
911 | { | ||
912 | struct proc_dir_entry *pde = seq->private; | ||
913 | u_int16_t af = (unsigned long)pde->data; | ||
914 | |||
915 | mutex_unlock(&xt[af].mutex); | ||
916 | } | 985 | } |
917 | 986 | ||
918 | static int xt_target_seq_show(struct seq_file *seq, void *v) | 987 | static int xt_target_seq_show(struct seq_file *seq, void *v) |
919 | { | 988 | { |
920 | struct xt_target *target = list_entry(v, struct xt_target, list); | 989 | const struct nf_mttg_trav *trav = seq->private; |
921 | 990 | const struct xt_target *target; | |
922 | if (strlen(target->name)) | 991 | |
923 | return seq_printf(seq, "%s\n", target->name); | 992 | switch (trav->class) { |
924 | else | 993 | case MTTG_TRAV_NFP_UNSPEC: |
925 | return 0; | 994 | case MTTG_TRAV_NFP_SPEC: |
995 | if (trav->curr == trav->head) | ||
996 | return 0; | ||
997 | target = list_entry(trav->curr, struct xt_target, list); | ||
998 | return (*target->name == '\0') ? 0 : | ||
999 | seq_printf(seq, "%s\n", target->name); | ||
1000 | } | ||
1001 | return 0; | ||
926 | } | 1002 | } |
927 | 1003 | ||
928 | static const struct seq_operations xt_target_seq_ops = { | 1004 | static const struct seq_operations xt_target_seq_ops = { |
929 | .start = xt_target_seq_start, | 1005 | .start = xt_target_seq_start, |
930 | .next = xt_target_seq_next, | 1006 | .next = xt_target_seq_next, |
931 | .stop = xt_target_seq_stop, | 1007 | .stop = xt_mttg_seq_stop, |
932 | .show = xt_target_seq_show, | 1008 | .show = xt_target_seq_show, |
933 | }; | 1009 | }; |
934 | 1010 | ||
935 | static int xt_target_open(struct inode *inode, struct file *file) | 1011 | static int xt_target_open(struct inode *inode, struct file *file) |
936 | { | 1012 | { |
1013 | struct seq_file *seq; | ||
1014 | struct nf_mttg_trav *trav; | ||
937 | int ret; | 1015 | int ret; |
938 | 1016 | ||
939 | ret = seq_open(file, &xt_target_seq_ops); | 1017 | trav = kmalloc(sizeof(*trav), GFP_KERNEL); |
940 | if (!ret) { | 1018 | if (trav == NULL) |
941 | struct seq_file *seq = file->private_data; | 1019 | return -ENOMEM; |
942 | 1020 | ||
943 | seq->private = PDE(inode); | 1021 | ret = seq_open(file, &xt_target_seq_ops); |
1022 | if (ret < 0) { | ||
1023 | kfree(trav); | ||
1024 | return ret; | ||
944 | } | 1025 | } |
945 | return ret; | 1026 | |
1027 | seq = file->private_data; | ||
1028 | seq->private = trav; | ||
1029 | trav->nfproto = (unsigned long)PDE(inode)->data; | ||
1030 | return 0; | ||
946 | } | 1031 | } |
947 | 1032 | ||
948 | static const struct file_operations xt_target_ops = { | 1033 | static const struct file_operations xt_target_ops = { |
@@ -950,7 +1035,7 @@ static const struct file_operations xt_target_ops = { | |||
950 | .open = xt_target_open, | 1035 | .open = xt_target_open, |
951 | .read = seq_read, | 1036 | .read = seq_read, |
952 | .llseek = seq_lseek, | 1037 | .llseek = seq_lseek, |
953 | .release = seq_release, | 1038 | .release = seq_release_private, |
954 | }; | 1039 | }; |
955 | 1040 | ||
956 | #define FORMAT_TABLES "_tables_names" | 1041 | #define FORMAT_TABLES "_tables_names" |
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index fe80b614a400..791e030ea903 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c | |||
@@ -542,7 +542,7 @@ recent_mt_proc_write(struct file *file, const char __user *input, | |||
542 | struct recent_entry *e; | 542 | struct recent_entry *e; |
543 | char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")]; | 543 | char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")]; |
544 | const char *c = buf; | 544 | const char *c = buf; |
545 | union nf_inet_addr addr; | 545 | union nf_inet_addr addr = {}; |
546 | u_int16_t family; | 546 | u_int16_t family; |
547 | bool add, succ; | 547 | bool add, succ; |
548 | 548 | ||