Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Conflicts: net/netfilter/nf_log.c The conflict in nf_log.c is that in 'net' we added CONFIG_PROC_FS protection around foo_proc_entry() calls to fix a build failure, whereas in Pablo's tree a guard if() test around a call is remove_proc_entry() was removed. Trivially resolved. Pablo Neira Ayuso says: ==================== The following patchset contains the first batch of Netfilter/IPVS updates for your net-next tree, they are: * Three patches with improvements and code refactorization for nfnetlink_queue, from Florian Westphal. * FTP helper now parses replies without brackets, as RFC1123 recommends, from Jeff Mahoney. * Rise a warning to tell everyone about ULOG deprecation, NFLOG has been already in the kernel tree for long time and supersedes the old logging over netlink stub, from myself. * Don't panic if we fail to load netfilter core framework, just bail out instead, from myself. * Add cond_resched_rcu, used by IPVS to allow rescheduling while walking over big hashtables, from Simon Horman. * Change type of IPVS sysctl_sync_qlen_max sysctl to avoid possible overflow, from Zhang Yanfei. * Use strlcpy instead of strncpy to skip zeroing of already initialized area to write the extension names in ebtables, from Chen Gang. * Use already existing per-cpu notrack object from xt_CT, from Eric Dumazet. * Save explicit socket lookup in xt_socket now that we have early demux, also from Eric Dumazet. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
143554ace8
@ -35,7 +35,7 @@ static inline void nf_inet_addr_mask(const union nf_inet_addr *a1,
|
||||
result->all[3] = a1->all[3] & mask->all[3];
|
||||
}
|
||||
|
||||
extern void netfilter_init(void);
|
||||
extern int netfilter_init(void);
|
||||
|
||||
/* Largest hook number + 1 */
|
||||
#define NF_MAX_HOOKS 8
|
||||
|
@ -2444,6 +2444,15 @@ extern int __cond_resched_softirq(void);
|
||||
__cond_resched_softirq(); \
|
||||
})
|
||||
|
||||
static inline void cond_resched_rcu(void)
|
||||
{
|
||||
#if defined(CONFIG_DEBUG_ATOMIC_SLEEP) || !defined(CONFIG_PREEMPT_RCU)
|
||||
rcu_read_unlock();
|
||||
cond_resched();
|
||||
rcu_read_lock();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Does a critical section need to be broken due to another
|
||||
* task waiting?: (technically does not depend on CONFIG_PREEMPT,
|
||||
|
@ -905,7 +905,7 @@ struct ip_vs_app {
|
||||
struct ipvs_master_sync_state {
|
||||
struct list_head sync_queue;
|
||||
struct ip_vs_sync_buff *sync_buff;
|
||||
int sync_queue_len;
|
||||
unsigned long sync_queue_len;
|
||||
unsigned int sync_queue_delay;
|
||||
struct task_struct *master_thread;
|
||||
struct delayed_work master_wakeup_work;
|
||||
@ -998,7 +998,7 @@ struct netns_ipvs {
|
||||
int sysctl_snat_reroute;
|
||||
int sysctl_sync_ver;
|
||||
int sysctl_sync_ports;
|
||||
int sysctl_sync_qlen_max;
|
||||
unsigned long sysctl_sync_qlen_max;
|
||||
int sysctl_sync_sock_size;
|
||||
int sysctl_cache_bypass;
|
||||
int sysctl_expire_nodest_conn;
|
||||
@ -1085,7 +1085,7 @@ static inline int sysctl_sync_ports(struct netns_ipvs *ipvs)
|
||||
return ACCESS_ONCE(ipvs->sysctl_sync_ports);
|
||||
}
|
||||
|
||||
static inline int sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
|
||||
static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
|
||||
{
|
||||
return ipvs->sysctl_sync_qlen_max;
|
||||
}
|
||||
@ -1138,7 +1138,7 @@ static inline int sysctl_sync_ports(struct netns_ipvs *ipvs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
|
||||
static inline unsigned long sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
|
||||
{
|
||||
return IPVS_SYNC_QLEN_MAX;
|
||||
}
|
||||
|
@ -15,5 +15,11 @@ struct netns_xt {
|
||||
struct ebt_table *frame_filter;
|
||||
struct ebt_table *frame_nat;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_IP_NF_TARGET_ULOG)
|
||||
bool ulog_warn_deprecated;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_BRIDGE_EBT_ULOG)
|
||||
bool ebt_ulog_warn_deprecated;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
@ -271,6 +271,12 @@ static int ebt_ulog_tg_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
struct ebt_ulog_info *uloginfo = par->targinfo;
|
||||
|
||||
if (!par->net->xt.ebt_ulog_warn_deprecated) {
|
||||
pr_info("ebt_ulog is deprecated and it will be removed soon, "
|
||||
"use ebt_nflog instead\n");
|
||||
par->net->xt.ebt_ulog_warn_deprecated = true;
|
||||
}
|
||||
|
||||
if (uloginfo->nlgroup > 31)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1339,7 +1339,7 @@ static inline int ebt_make_matchname(const struct ebt_entry_match *m,
|
||||
|
||||
/* ebtables expects 32 bytes long names but xt_match names are 29 bytes
|
||||
long. Copy 29 bytes and fill remaining bytes with zeroes. */
|
||||
strncpy(name, m->u.match->name, sizeof(name));
|
||||
strlcpy(name, m->u.match->name, sizeof(name));
|
||||
if (copy_to_user(hlp, name, EBT_FUNCTION_MAXNAMELEN))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@ -1351,7 +1351,7 @@ static inline int ebt_make_watchername(const struct ebt_entry_watcher *w,
|
||||
char __user *hlp = ubase + ((char *)w - base);
|
||||
char name[EBT_FUNCTION_MAXNAMELEN] = {};
|
||||
|
||||
strncpy(name, w->u.watcher->name, sizeof(name));
|
||||
strlcpy(name, w->u.watcher->name, sizeof(name));
|
||||
if (copy_to_user(hlp , name, EBT_FUNCTION_MAXNAMELEN))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@ -1377,7 +1377,7 @@ ebt_make_names(struct ebt_entry *e, const char *base, char __user *ubase)
|
||||
ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
strncpy(name, t->u.target->name, sizeof(name));
|
||||
strlcpy(name, t->u.target->name, sizeof(name));
|
||||
if (copy_to_user(hlp, name, EBT_FUNCTION_MAXNAMELEN))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
@ -111,7 +111,7 @@ config IP_NF_TARGET_REJECT
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_TARGET_ULOG
|
||||
tristate "ULOG target support"
|
||||
tristate "ULOG target support (obsolete)"
|
||||
default m if NETFILTER_ADVANCED=n
|
||||
---help---
|
||||
|
||||
|
@ -330,6 +330,12 @@ static int ulog_tg_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
const struct ipt_ulog_info *loginfo = par->targinfo;
|
||||
|
||||
if (!par->net->xt.ulog_warn_deprecated) {
|
||||
pr_info("ULOG is deprecated and it will be removed soon, "
|
||||
"use NFLOG instead\n");
|
||||
par->net->xt.ulog_warn_deprecated = true;
|
||||
}
|
||||
|
||||
if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
|
||||
pr_debug("prefix not null-terminated\n");
|
||||
return -EINVAL;
|
||||
|
@ -304,17 +304,26 @@ static struct pernet_operations netfilter_net_ops = {
|
||||
.exit = netfilter_net_exit,
|
||||
};
|
||||
|
||||
void __init netfilter_init(void)
|
||||
int __init netfilter_init(void)
|
||||
{
|
||||
int i, h;
|
||||
int i, h, ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) {
|
||||
for (h = 0; h < NF_MAX_HOOKS; h++)
|
||||
INIT_LIST_HEAD(&nf_hooks[i][h]);
|
||||
}
|
||||
|
||||
if (register_pernet_subsys(&netfilter_net_ops) < 0)
|
||||
panic("cannot create netfilter proc entry");
|
||||
ret = register_pernet_subsys(&netfilter_net_ops);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (netfilter_log_init() < 0)
|
||||
panic("cannot initialize nf_log");
|
||||
ret = netfilter_log_init();
|
||||
if (ret < 0)
|
||||
goto err_pernet;
|
||||
|
||||
return 0;
|
||||
err_pernet:
|
||||
unregister_pernet_subsys(&netfilter_net_ops);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
@ -975,8 +975,7 @@ static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos)
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
rcu_read_lock();
|
||||
cond_resched_rcu();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -1015,8 +1014,7 @@ static void *ip_vs_conn_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
iter->l = &ip_vs_conn_tab[idx];
|
||||
return cp;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
rcu_read_lock();
|
||||
cond_resched_rcu();
|
||||
}
|
||||
iter->l = NULL;
|
||||
return NULL;
|
||||
@ -1206,17 +1204,13 @@ void ip_vs_random_dropentry(struct net *net)
|
||||
int idx;
|
||||
struct ip_vs_conn *cp, *cp_c;
|
||||
|
||||
rcu_read_lock();
|
||||
/*
|
||||
* Randomly scan 1/32 of the whole table every second
|
||||
*/
|
||||
for (idx = 0; idx < (ip_vs_conn_tab_size>>5); idx++) {
|
||||
unsigned int hash = net_random() & ip_vs_conn_tab_mask;
|
||||
|
||||
/*
|
||||
* Lock is actually needed in this loop.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
|
||||
hlist_for_each_entry_rcu(cp, &ip_vs_conn_tab[hash], c_list) {
|
||||
if (cp->flags & IP_VS_CONN_F_TEMPLATE)
|
||||
/* connection template */
|
||||
@ -1252,8 +1246,9 @@ void ip_vs_random_dropentry(struct net *net)
|
||||
__ip_vs_conn_put(cp);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
cond_resched_rcu();
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
|
||||
@ -1267,11 +1262,8 @@ static void ip_vs_conn_flush(struct net *net)
|
||||
struct netns_ipvs *ipvs = net_ipvs(net);
|
||||
|
||||
flush_again:
|
||||
rcu_read_lock();
|
||||
for (idx = 0; idx < ip_vs_conn_tab_size; idx++) {
|
||||
/*
|
||||
* Lock is actually needed in this loop.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
|
||||
hlist_for_each_entry_rcu(cp, &ip_vs_conn_tab[idx], c_list) {
|
||||
if (!ip_vs_conn_net_eq(cp, net))
|
||||
@ -1286,8 +1278,9 @@ flush_again:
|
||||
__ip_vs_conn_put(cp);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
cond_resched_rcu();
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
/* the counter may be not NULL, because maybe some conn entries
|
||||
are run by slow timer handler or unhashed but still referred */
|
||||
|
@ -1716,9 +1716,9 @@ static struct ctl_table vs_vars[] = {
|
||||
},
|
||||
{
|
||||
.procname = "sync_qlen_max",
|
||||
.maxlen = sizeof(int),
|
||||
.maxlen = sizeof(unsigned long),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
.proc_handler = proc_doulongvec_minmax,
|
||||
},
|
||||
{
|
||||
.procname = "sync_sock_size",
|
||||
|
@ -55,10 +55,14 @@ unsigned int (*nf_nat_ftp_hook)(struct sk_buff *skb,
|
||||
struct nf_conntrack_expect *exp);
|
||||
EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
|
||||
|
||||
static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char);
|
||||
static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char);
|
||||
static int try_rfc959(const char *, size_t, struct nf_conntrack_man *,
|
||||
char, unsigned int *);
|
||||
static int try_rfc1123(const char *, size_t, struct nf_conntrack_man *,
|
||||
char, unsigned int *);
|
||||
static int try_eprt(const char *, size_t, struct nf_conntrack_man *,
|
||||
char, unsigned int *);
|
||||
static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *,
|
||||
char);
|
||||
char, unsigned int *);
|
||||
|
||||
static struct ftp_search {
|
||||
const char *pattern;
|
||||
@ -66,7 +70,7 @@ static struct ftp_search {
|
||||
char skip;
|
||||
char term;
|
||||
enum nf_ct_ftp_type ftptype;
|
||||
int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char);
|
||||
int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char, unsigned int *);
|
||||
} search[IP_CT_DIR_MAX][2] = {
|
||||
[IP_CT_DIR_ORIGINAL] = {
|
||||
{
|
||||
@ -90,10 +94,8 @@ static struct ftp_search {
|
||||
{
|
||||
.pattern = "227 ",
|
||||
.plen = sizeof("227 ") - 1,
|
||||
.skip = '(',
|
||||
.term = ')',
|
||||
.ftptype = NF_CT_FTP_PASV,
|
||||
.getnum = try_rfc959,
|
||||
.getnum = try_rfc1123,
|
||||
},
|
||||
{
|
||||
.pattern = "229 ",
|
||||
@ -132,8 +134,9 @@ static int try_number(const char *data, size_t dlen, u_int32_t array[],
|
||||
i++;
|
||||
else {
|
||||
/* Unexpected character; true if it's the
|
||||
terminator and we're finished. */
|
||||
if (*data == term && i == array_size - 1)
|
||||
terminator (or we don't care about one)
|
||||
and we're finished. */
|
||||
if ((*data == term || !term) && i == array_size - 1)
|
||||
return len;
|
||||
|
||||
pr_debug("Char %u (got %u nums) `%u' unexpected\n",
|
||||
@ -148,7 +151,8 @@ static int try_number(const char *data, size_t dlen, u_int32_t array[],
|
||||
|
||||
/* Returns 0, or length of numbers: 192,168,1,1,5,6 */
|
||||
static int try_rfc959(const char *data, size_t dlen,
|
||||
struct nf_conntrack_man *cmd, char term)
|
||||
struct nf_conntrack_man *cmd, char term,
|
||||
unsigned int *offset)
|
||||
{
|
||||
int length;
|
||||
u_int32_t array[6];
|
||||
@ -163,6 +167,33 @@ static int try_rfc959(const char *data, size_t dlen,
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
* From RFC 1123:
|
||||
* The format of the 227 reply to a PASV command is not
|
||||
* well standardized. In particular, an FTP client cannot
|
||||
* assume that the parentheses shown on page 40 of RFC-959
|
||||
* will be present (and in fact, Figure 3 on page 43 omits
|
||||
* them). Therefore, a User-FTP program that interprets
|
||||
* the PASV reply must scan the reply for the first digit
|
||||
* of the host and port numbers.
|
||||
*/
|
||||
static int try_rfc1123(const char *data, size_t dlen,
|
||||
struct nf_conntrack_man *cmd, char term,
|
||||
unsigned int *offset)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < dlen; i++)
|
||||
if (isdigit(data[i]))
|
||||
break;
|
||||
|
||||
if (i == dlen)
|
||||
return 0;
|
||||
|
||||
*offset += i;
|
||||
|
||||
return try_rfc959(data + i, dlen - i, cmd, 0, offset);
|
||||
}
|
||||
|
||||
/* Grab port: number up to delimiter */
|
||||
static int get_port(const char *data, int start, size_t dlen, char delim,
|
||||
__be16 *port)
|
||||
@ -191,7 +222,7 @@ static int get_port(const char *data, int start, size_t dlen, char delim,
|
||||
|
||||
/* Returns 0, or length of numbers: |1|132.235.1.2|6275| or |2|3ffe::1|6275| */
|
||||
static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd,
|
||||
char term)
|
||||
char term, unsigned int *offset)
|
||||
{
|
||||
char delim;
|
||||
int length;
|
||||
@ -239,7 +270,8 @@ static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd,
|
||||
|
||||
/* Returns 0, or length of numbers: |||6446| */
|
||||
static int try_epsv_response(const char *data, size_t dlen,
|
||||
struct nf_conntrack_man *cmd, char term)
|
||||
struct nf_conntrack_man *cmd, char term,
|
||||
unsigned int *offset)
|
||||
{
|
||||
char delim;
|
||||
|
||||
@ -261,9 +293,10 @@ static int find_pattern(const char *data, size_t dlen,
|
||||
unsigned int *numlen,
|
||||
struct nf_conntrack_man *cmd,
|
||||
int (*getnum)(const char *, size_t,
|
||||
struct nf_conntrack_man *, char))
|
||||
struct nf_conntrack_man *, char,
|
||||
unsigned int *))
|
||||
{
|
||||
size_t i;
|
||||
size_t i = plen;
|
||||
|
||||
pr_debug("find_pattern `%s': dlen = %Zu\n", pattern, dlen);
|
||||
if (dlen == 0)
|
||||
@ -293,16 +326,18 @@ static int find_pattern(const char *data, size_t dlen,
|
||||
pr_debug("Pattern matches!\n");
|
||||
/* Now we've found the constant string, try to skip
|
||||
to the 'skip' character */
|
||||
for (i = plen; data[i] != skip; i++)
|
||||
if (i == dlen - 1) return -1;
|
||||
if (skip) {
|
||||
for (i = plen; data[i] != skip; i++)
|
||||
if (i == dlen - 1) return -1;
|
||||
|
||||
/* Skip over the last character */
|
||||
i++;
|
||||
/* Skip over the last character */
|
||||
i++;
|
||||
}
|
||||
|
||||
pr_debug("Skipped up to `%c'!\n", skip);
|
||||
|
||||
*numoff = i;
|
||||
*numlen = getnum(data + i, dlen - i, cmd, term);
|
||||
*numlen = getnum(data + i, dlen - i, cmd, term, numoff);
|
||||
if (!*numlen)
|
||||
return -1;
|
||||
|
||||
|
@ -369,9 +369,7 @@ static int __net_init nf_log_net_init(struct net *net)
|
||||
|
||||
out_sysctl:
|
||||
#ifdef CONFIG_PROC_FS
|
||||
/* For init_net: errors will trigger panic, don't unroll on error. */
|
||||
if (!net_eq(net, &init_net))
|
||||
remove_proc_entry("nf_log", net->nf.proc_netfilter);
|
||||
remove_proc_entry("nf_log", net->nf.proc_netfilter);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
@ -41,6 +41,14 @@
|
||||
|
||||
#define NFQNL_QMAX_DEFAULT 1024
|
||||
|
||||
/* We're using struct nlattr which has 16bit nla_len. Note that nla_len
|
||||
* includes the header length. Thus, the maximum packet length that we
|
||||
* support is 65531 bytes. We send truncated packets if the specified length
|
||||
* is larger than that. Userspace can check for presence of NFQA_CAP_LEN
|
||||
* attribute to detect truncation.
|
||||
*/
|
||||
#define NFQNL_MAX_COPY_RANGE (0xffff - NLA_HDRLEN)
|
||||
|
||||
struct nfqnl_instance {
|
||||
struct hlist_node hlist; /* global list of queues */
|
||||
struct rcu_head rcu;
|
||||
@ -122,7 +130,7 @@ instance_create(struct nfnl_queue_net *q, u_int16_t queue_num,
|
||||
inst->queue_num = queue_num;
|
||||
inst->peer_portid = portid;
|
||||
inst->queue_maxlen = NFQNL_QMAX_DEFAULT;
|
||||
inst->copy_range = 0xffff;
|
||||
inst->copy_range = NFQNL_MAX_COPY_RANGE;
|
||||
inst->copy_mode = NFQNL_COPY_NONE;
|
||||
spin_lock_init(&inst->lock);
|
||||
INIT_LIST_HEAD(&inst->queue_list);
|
||||
@ -333,10 +341,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
|
||||
return NULL;
|
||||
|
||||
data_len = ACCESS_ONCE(queue->copy_range);
|
||||
if (data_len == 0 || data_len > entskb->len)
|
||||
if (data_len > entskb->len)
|
||||
data_len = entskb->len;
|
||||
|
||||
|
||||
if (!entskb->head_frag ||
|
||||
skb_headlen(entskb) < L1_CACHE_BYTES ||
|
||||
skb_shinfo(entskb)->nr_frags >= MAX_SKB_FRAGS)
|
||||
@ -465,7 +472,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
|
||||
if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (cap_len > 0 && nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len)))
|
||||
if (cap_len > data_len &&
|
||||
nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nfqnl_put_packet_info(skb, entskb))
|
||||
@ -509,10 +517,6 @@ __nfqnl_enqueue_packet(struct net *net, struct nfqnl_instance *queue,
|
||||
}
|
||||
spin_lock_bh(&queue->lock);
|
||||
|
||||
if (!queue->peer_portid) {
|
||||
err = -EINVAL;
|
||||
goto err_out_free_nskb;
|
||||
}
|
||||
if (queue->queue_total >= queue->queue_maxlen) {
|
||||
if (queue->flags & NFQA_CFG_F_FAIL_OPEN) {
|
||||
failopen = 1;
|
||||
@ -731,13 +735,8 @@ nfqnl_set_mode(struct nfqnl_instance *queue,
|
||||
|
||||
case NFQNL_COPY_PACKET:
|
||||
queue->copy_mode = mode;
|
||||
/* We're using struct nlattr which has 16bit nla_len. Note that
|
||||
* nla_len includes the header length. Thus, the maximum packet
|
||||
* length that we support is 65531 bytes. We send truncated
|
||||
* packets if the specified length is larger than that.
|
||||
*/
|
||||
if (range > 0xffff - NLA_HDRLEN)
|
||||
queue->copy_range = 0xffff - NLA_HDRLEN;
|
||||
if (range == 0 || range > NFQNL_MAX_COPY_RANGE)
|
||||
queue->copy_range = NFQNL_MAX_COPY_RANGE;
|
||||
else
|
||||
queue->copy_range = range;
|
||||
break;
|
||||
|
@ -26,6 +26,9 @@ static inline int xt_ct_target(struct sk_buff *skb, struct nf_conn *ct)
|
||||
if (skb->nfct != NULL)
|
||||
return XT_CONTINUE;
|
||||
|
||||
/* special case the untracked ct : we want the percpu object */
|
||||
if (!ct)
|
||||
ct = nf_ct_untracked_get();
|
||||
atomic_inc(&ct->ct_general.use);
|
||||
skb->nfct = &ct->ct_general;
|
||||
skb->nfctinfo = IP_CT_NEW;
|
||||
@ -186,8 +189,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par,
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
if (info->flags & XT_CT_NOTRACK) {
|
||||
ct = nf_ct_untracked_get();
|
||||
atomic_inc(&ct->ct_general.use);
|
||||
ct = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -311,7 +313,7 @@ static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par,
|
||||
struct nf_conn *ct = info->ct;
|
||||
struct nf_conn_help *help;
|
||||
|
||||
if (!nf_ct_is_untracked(ct)) {
|
||||
if (ct && !nf_ct_is_untracked(ct)) {
|
||||
help = nfct_help(ct);
|
||||
if (help)
|
||||
module_put(help->helper->me);
|
||||
@ -319,8 +321,8 @@ static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par,
|
||||
nf_ct_l3proto_module_put(par->family);
|
||||
|
||||
xt_ct_destroy_timeout(ct);
|
||||
nf_ct_put(info->ct);
|
||||
}
|
||||
nf_ct_put(info->ct);
|
||||
}
|
||||
|
||||
static void xt_ct_tg_destroy_v0(const struct xt_tgdtor_param *par)
|
||||
|
@ -107,7 +107,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
struct udphdr _hdr, *hp = NULL;
|
||||
struct sock *sk;
|
||||
struct sock *sk = skb->sk;
|
||||
__be32 uninitialized_var(daddr), uninitialized_var(saddr);
|
||||
__be16 uninitialized_var(dport), uninitialized_var(sport);
|
||||
u8 uninitialized_var(protocol);
|
||||
@ -155,9 +155,11 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
|
||||
}
|
||||
#endif
|
||||
|
||||
sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol,
|
||||
saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY);
|
||||
if (sk != NULL) {
|
||||
if (!sk)
|
||||
sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol,
|
||||
saddr, daddr, sport, dport,
|
||||
par->in, NFT_LOOKUP_ANY);
|
||||
if (sk) {
|
||||
bool wildcard;
|
||||
bool transparent = true;
|
||||
|
||||
@ -173,7 +175,8 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
|
||||
(sk->sk_state == TCP_TIME_WAIT &&
|
||||
inet_twsk(sk)->tw_transparent));
|
||||
|
||||
xt_socket_put_sk(sk);
|
||||
if (sk != skb->sk)
|
||||
xt_socket_put_sk(sk);
|
||||
|
||||
if (wildcard || !transparent)
|
||||
sk = NULL;
|
||||
@ -260,7 +263,7 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
{
|
||||
struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
struct udphdr _hdr, *hp = NULL;
|
||||
struct sock *sk;
|
||||
struct sock *sk = skb->sk;
|
||||
struct in6_addr *daddr = NULL, *saddr = NULL;
|
||||
__be16 uninitialized_var(dport), uninitialized_var(sport);
|
||||
int thoff = 0, uninitialized_var(tproto);
|
||||
@ -291,9 +294,11 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
return false;
|
||||
}
|
||||
|
||||
sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto,
|
||||
saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY);
|
||||
if (sk != NULL) {
|
||||
if (!sk)
|
||||
sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto,
|
||||
saddr, daddr, sport, dport,
|
||||
par->in, NFT_LOOKUP_ANY);
|
||||
if (sk) {
|
||||
bool wildcard;
|
||||
bool transparent = true;
|
||||
|
||||
@ -309,7 +314,8 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
(sk->sk_state == TCP_TIME_WAIT &&
|
||||
inet_twsk(sk)->tw_transparent));
|
||||
|
||||
xt_socket_put_sk(sk);
|
||||
if (sk != skb->sk)
|
||||
xt_socket_put_sk(sk);
|
||||
|
||||
if (wildcard || !transparent)
|
||||
sk = NULL;
|
||||
|
@ -2641,7 +2641,9 @@ static int __init sock_init(void)
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NETFILTER
|
||||
netfilter_init();
|
||||
err = netfilter_init();
|
||||
if (err)
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NETWORK_PHY_TIMESTAMPING
|
||||
|
Loading…
Reference in New Issue
Block a user