mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-14 12:49:08 +00:00
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
This commit is contained in:
commit
b1109bf085
@ -3836,6 +3836,7 @@ NETWORKING DRIVERS
|
|||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
W: http://www.linuxfoundation.org/en/Net
|
W: http://www.linuxfoundation.org/en/Net
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
|
||||||
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
F: drivers/net/
|
F: drivers/net/
|
||||||
F: include/linux/if_*
|
F: include/linux/if_*
|
||||||
|
@ -808,6 +808,7 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv,
|
|||||||
|
|
||||||
exit:
|
exit:
|
||||||
sdio_release_host(card->func);
|
sdio_release_host(card->func);
|
||||||
|
kfree(tmpbuf);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -921,7 +921,7 @@ static int ax_probe(struct platform_device *pdev)
|
|||||||
size = (res->end - res->start) + 1;
|
size = (res->end - res->start) + 1;
|
||||||
|
|
||||||
ax->mem2 = request_mem_region(res->start, size, pdev->name);
|
ax->mem2 = request_mem_region(res->start, size, pdev->name);
|
||||||
if (ax->mem == NULL) {
|
if (ax->mem2 == NULL) {
|
||||||
dev_err(&pdev->dev, "cannot reserve registers\n");
|
dev_err(&pdev->dev, "cannot reserve registers\n");
|
||||||
ret = -ENXIO;
|
ret = -ENXIO;
|
||||||
goto exit_mem1;
|
goto exit_mem1;
|
||||||
|
@ -2080,6 +2080,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
|
|||||||
struct sge_fl *fl, int len, int complete)
|
struct sge_fl *fl, int len, int complete)
|
||||||
{
|
{
|
||||||
struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
|
struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
|
||||||
|
struct port_info *pi = netdev_priv(qs->netdev);
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
struct cpl_rx_pkt *cpl;
|
struct cpl_rx_pkt *cpl;
|
||||||
struct skb_frag_struct *rx_frag;
|
struct skb_frag_struct *rx_frag;
|
||||||
@ -2117,11 +2118,18 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
|
|||||||
|
|
||||||
if (!nr_frags) {
|
if (!nr_frags) {
|
||||||
offset = 2 + sizeof(struct cpl_rx_pkt);
|
offset = 2 + sizeof(struct cpl_rx_pkt);
|
||||||
qs->lro_va = sd->pg_chunk.va + 2;
|
cpl = qs->lro_va = sd->pg_chunk.va + 2;
|
||||||
}
|
|
||||||
len -= offset;
|
|
||||||
|
|
||||||
prefetch(qs->lro_va);
|
if ((pi->rx_offload & T3_RX_CSUM) &&
|
||||||
|
cpl->csum_valid && cpl->csum == htons(0xffff)) {
|
||||||
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
|
qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
|
||||||
|
} else
|
||||||
|
skb->ip_summed = CHECKSUM_NONE;
|
||||||
|
} else
|
||||||
|
cpl = qs->lro_va;
|
||||||
|
|
||||||
|
len -= offset;
|
||||||
|
|
||||||
rx_frag += nr_frags;
|
rx_frag += nr_frags;
|
||||||
rx_frag->page = sd->pg_chunk.page;
|
rx_frag->page = sd->pg_chunk.page;
|
||||||
@ -2137,12 +2145,8 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
|
skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
|
||||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
||||||
cpl = qs->lro_va;
|
|
||||||
|
|
||||||
if (unlikely(cpl->vlan_valid)) {
|
if (unlikely(cpl->vlan_valid)) {
|
||||||
struct net_device *dev = qs->netdev;
|
|
||||||
struct port_info *pi = netdev_priv(dev);
|
|
||||||
struct vlan_group *grp = pi->vlan_grp;
|
struct vlan_group *grp = pi->vlan_grp;
|
||||||
|
|
||||||
if (likely(grp != NULL)) {
|
if (likely(grp != NULL)) {
|
||||||
|
@ -421,6 +421,8 @@ static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector)
|
|||||||
msixbm = E1000_EICR_RX_QUEUE0 << rx_queue;
|
msixbm = E1000_EICR_RX_QUEUE0 << rx_queue;
|
||||||
if (tx_queue > IGB_N0_QUEUE)
|
if (tx_queue > IGB_N0_QUEUE)
|
||||||
msixbm |= E1000_EICR_TX_QUEUE0 << tx_queue;
|
msixbm |= E1000_EICR_TX_QUEUE0 << tx_queue;
|
||||||
|
if (!adapter->msix_entries && msix_vector == 0)
|
||||||
|
msixbm |= E1000_EIMS_OTHER;
|
||||||
array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
|
array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
|
||||||
q_vector->eims_value = msixbm;
|
q_vector->eims_value = msixbm;
|
||||||
break;
|
break;
|
||||||
@ -877,7 +879,6 @@ static int igb_request_irq(struct igb_adapter *adapter)
|
|||||||
{
|
{
|
||||||
struct net_device *netdev = adapter->netdev;
|
struct net_device *netdev = adapter->netdev;
|
||||||
struct pci_dev *pdev = adapter->pdev;
|
struct pci_dev *pdev = adapter->pdev;
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (adapter->msix_entries) {
|
if (adapter->msix_entries) {
|
||||||
@ -909,20 +910,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
|
|||||||
igb_setup_all_tx_resources(adapter);
|
igb_setup_all_tx_resources(adapter);
|
||||||
igb_setup_all_rx_resources(adapter);
|
igb_setup_all_rx_resources(adapter);
|
||||||
} else {
|
} else {
|
||||||
switch (hw->mac.type) {
|
igb_assign_vector(adapter->q_vector[0], 0);
|
||||||
case e1000_82575:
|
|
||||||
wr32(E1000_MSIXBM(0),
|
|
||||||
(E1000_EICR_RX_QUEUE0 |
|
|
||||||
E1000_EICR_TX_QUEUE0 |
|
|
||||||
E1000_EIMS_OTHER));
|
|
||||||
break;
|
|
||||||
case e1000_82580:
|
|
||||||
case e1000_82576:
|
|
||||||
wr32(E1000_IVAR0, E1000_IVAR_VALID);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adapter->flags & IGB_FLAG_HAS_MSI) {
|
if (adapter->flags & IGB_FLAG_HAS_MSI) {
|
||||||
@ -1140,6 +1128,8 @@ int igb_up(struct igb_adapter *adapter)
|
|||||||
}
|
}
|
||||||
if (adapter->msix_entries)
|
if (adapter->msix_entries)
|
||||||
igb_configure_msix(adapter);
|
igb_configure_msix(adapter);
|
||||||
|
else
|
||||||
|
igb_assign_vector(adapter->q_vector[0], 0);
|
||||||
|
|
||||||
/* Clear any pending interrupts. */
|
/* Clear any pending interrupts. */
|
||||||
rd32(E1000_ICR);
|
rd32(E1000_ICR);
|
||||||
|
@ -11,6 +11,8 @@ struct nf_conntrack_ecache;
|
|||||||
struct netns_ct {
|
struct netns_ct {
|
||||||
atomic_t count;
|
atomic_t count;
|
||||||
unsigned int expect_count;
|
unsigned int expect_count;
|
||||||
|
unsigned int htable_size;
|
||||||
|
struct kmem_cache *nf_conntrack_cachep;
|
||||||
struct hlist_nulls_head *hash;
|
struct hlist_nulls_head *hash;
|
||||||
struct hlist_head *expect_hash;
|
struct hlist_head *expect_hash;
|
||||||
struct hlist_nulls_head unconfirmed;
|
struct hlist_nulls_head unconfirmed;
|
||||||
@ -28,5 +30,6 @@ struct netns_ct {
|
|||||||
#endif
|
#endif
|
||||||
int hash_vmalloc;
|
int hash_vmalloc;
|
||||||
int expect_vmalloc;
|
int expect_vmalloc;
|
||||||
|
char *slabname;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,6 +40,7 @@ struct netns_ipv4 {
|
|||||||
struct xt_table *iptable_security;
|
struct xt_table *iptable_security;
|
||||||
struct xt_table *nat_table;
|
struct xt_table *nat_table;
|
||||||
struct hlist_head *nat_bysource;
|
struct hlist_head *nat_bysource;
|
||||||
|
unsigned int nat_htable_size;
|
||||||
int nat_vmalloced;
|
int nat_vmalloced;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -377,6 +377,9 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
|
|||||||
|
|
||||||
if (acl->state == BT_CONNECTED &&
|
if (acl->state == BT_CONNECTED &&
|
||||||
(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
|
(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
|
||||||
|
acl->power_save = 1;
|
||||||
|
hci_conn_enter_active_mode(acl);
|
||||||
|
|
||||||
if (lmp_esco_capable(hdev))
|
if (lmp_esco_capable(hdev))
|
||||||
hci_setup_sync(sco, acl->handle);
|
hci_setup_sync(sco, acl->handle);
|
||||||
else
|
else
|
||||||
|
@ -1699,6 +1699,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1c: /* SCO interval rejected */
|
case 0x1c: /* SCO interval rejected */
|
||||||
|
case 0x1a: /* Unsupported Remote Feature */
|
||||||
case 0x1f: /* Unspecified error */
|
case 0x1f: /* Unspecified error */
|
||||||
if (conn->out && conn->attempt < 2) {
|
if (conn->out && conn->attempt < 2) {
|
||||||
conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
|
conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
|
||||||
|
@ -703,29 +703,9 @@ static void hidp_close(struct hid_device *hid)
|
|||||||
static int hidp_parse(struct hid_device *hid)
|
static int hidp_parse(struct hid_device *hid)
|
||||||
{
|
{
|
||||||
struct hidp_session *session = hid->driver_data;
|
struct hidp_session *session = hid->driver_data;
|
||||||
struct hidp_connadd_req *req = session->req;
|
|
||||||
unsigned char *buf;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
buf = kmalloc(req->rd_size, GFP_KERNEL);
|
return hid_parse_report(session->hid, session->rd_data,
|
||||||
if (!buf)
|
session->rd_size);
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
if (copy_from_user(buf, req->rd_data, req->rd_size)) {
|
|
||||||
kfree(buf);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = hid_parse_report(session->hid, buf, req->rd_size);
|
|
||||||
|
|
||||||
kfree(buf);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
session->req = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hidp_start(struct hid_device *hid)
|
static int hidp_start(struct hid_device *hid)
|
||||||
@ -770,12 +750,24 @@ static int hidp_setup_hid(struct hidp_session *session,
|
|||||||
bdaddr_t src, dst;
|
bdaddr_t src, dst;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
session->rd_data = kzalloc(req->rd_size, GFP_KERNEL);
|
||||||
|
if (!session->rd_data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (copy_from_user(session->rd_data, req->rd_data, req->rd_size)) {
|
||||||
|
err = -EFAULT;
|
||||||
|
goto fault;
|
||||||
|
}
|
||||||
|
session->rd_size = req->rd_size;
|
||||||
|
|
||||||
hid = hid_allocate_device();
|
hid = hid_allocate_device();
|
||||||
if (IS_ERR(hid))
|
if (IS_ERR(hid)) {
|
||||||
return PTR_ERR(hid);
|
err = PTR_ERR(hid);
|
||||||
|
goto fault;
|
||||||
|
}
|
||||||
|
|
||||||
session->hid = hid;
|
session->hid = hid;
|
||||||
session->req = req;
|
|
||||||
hid->driver_data = session;
|
hid->driver_data = session;
|
||||||
|
|
||||||
baswap(&src, &bt_sk(session->ctrl_sock->sk)->src);
|
baswap(&src, &bt_sk(session->ctrl_sock->sk)->src);
|
||||||
@ -806,6 +798,10 @@ failed:
|
|||||||
hid_destroy_device(hid);
|
hid_destroy_device(hid);
|
||||||
session->hid = NULL;
|
session->hid = NULL;
|
||||||
|
|
||||||
|
fault:
|
||||||
|
kfree(session->rd_data);
|
||||||
|
session->rd_data = NULL;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,6 +896,9 @@ unlink:
|
|||||||
session->hid = NULL;
|
session->hid = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kfree(session->rd_data);
|
||||||
|
session->rd_data = NULL;
|
||||||
|
|
||||||
purge:
|
purge:
|
||||||
skb_queue_purge(&session->ctrl_transmit);
|
skb_queue_purge(&session->ctrl_transmit);
|
||||||
skb_queue_purge(&session->intr_transmit);
|
skb_queue_purge(&session->intr_transmit);
|
||||||
|
@ -154,7 +154,9 @@ struct hidp_session {
|
|||||||
struct sk_buff_head ctrl_transmit;
|
struct sk_buff_head ctrl_transmit;
|
||||||
struct sk_buff_head intr_transmit;
|
struct sk_buff_head intr_transmit;
|
||||||
|
|
||||||
struct hidp_connadd_req *req;
|
/* Report descriptor */
|
||||||
|
__u8 *rd_data;
|
||||||
|
uint rd_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void hidp_schedule(struct hidp_session *session)
|
static inline void hidp_schedule(struct hidp_session *session)
|
||||||
|
@ -252,7 +252,6 @@ static void rfcomm_session_timeout(unsigned long arg)
|
|||||||
BT_DBG("session %p state %ld", s, s->state);
|
BT_DBG("session %p state %ld", s, s->state);
|
||||||
|
|
||||||
set_bit(RFCOMM_TIMED_OUT, &s->flags);
|
set_bit(RFCOMM_TIMED_OUT, &s->flags);
|
||||||
rfcomm_session_put(s);
|
|
||||||
rfcomm_schedule(RFCOMM_SCHED_TIMEO);
|
rfcomm_schedule(RFCOMM_SCHED_TIMEO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1151,7 +1150,11 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BT_DISCONN:
|
case BT_DISCONN:
|
||||||
rfcomm_session_put(s);
|
/* When socket is closed and we are not RFCOMM
|
||||||
|
* initiator rfcomm_process_rx already calls
|
||||||
|
* rfcomm_session_put() */
|
||||||
|
if (s->sock->sk->sk_state != BT_CLOSED)
|
||||||
|
rfcomm_session_put(s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1920,6 +1923,7 @@ static inline void rfcomm_process_sessions(void)
|
|||||||
if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
|
if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
|
||||||
s->state = BT_DISCONN;
|
s->state = BT_DISCONN;
|
||||||
rfcomm_send_disc(s, 0);
|
rfcomm_send_disc(s, 0);
|
||||||
|
rfcomm_session_put(s);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <net/net_namespace.h>
|
#include <net/net_namespace.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
#include <net/dst.h>
|
#include <net/dst.h>
|
||||||
|
|
||||||
@ -79,6 +80,7 @@ loop:
|
|||||||
while ((dst = next) != NULL) {
|
while ((dst = next) != NULL) {
|
||||||
next = dst->next;
|
next = dst->next;
|
||||||
prefetch(&next->next);
|
prefetch(&next->next);
|
||||||
|
cond_resched();
|
||||||
if (likely(atomic_read(&dst->__refcnt))) {
|
if (likely(atomic_read(&dst->__refcnt))) {
|
||||||
last->next = dst;
|
last->next = dst;
|
||||||
last = dst;
|
last = dst;
|
||||||
|
@ -3524,6 +3524,7 @@ static int pktgen_thread_worker(void *arg)
|
|||||||
wait_event_interruptible_timeout(t->queue,
|
wait_event_interruptible_timeout(t->queue,
|
||||||
t->control != 0,
|
t->control != 0,
|
||||||
HZ/10);
|
HZ/10);
|
||||||
|
try_to_freeze();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -925,10 +925,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
|
|||||||
if (t && !IS_ERR(t)) {
|
if (t && !IS_ERR(t)) {
|
||||||
struct arpt_getinfo info;
|
struct arpt_getinfo info;
|
||||||
const struct xt_table_info *private = t->private;
|
const struct xt_table_info *private = t->private;
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
|
struct xt_table_info tmp;
|
||||||
|
|
||||||
if (compat) {
|
if (compat) {
|
||||||
struct xt_table_info tmp;
|
|
||||||
ret = compat_table_info(private, &tmp);
|
ret = compat_table_info(private, &tmp);
|
||||||
xt_compat_flush_offsets(NFPROTO_ARP);
|
xt_compat_flush_offsets(NFPROTO_ARP);
|
||||||
private = &tmp;
|
private = &tmp;
|
||||||
|
@ -1132,10 +1132,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
|
|||||||
if (t && !IS_ERR(t)) {
|
if (t && !IS_ERR(t)) {
|
||||||
struct ipt_getinfo info;
|
struct ipt_getinfo info;
|
||||||
const struct xt_table_info *private = t->private;
|
const struct xt_table_info *private = t->private;
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
|
struct xt_table_info tmp;
|
||||||
|
|
||||||
if (compat) {
|
if (compat) {
|
||||||
struct xt_table_info tmp;
|
|
||||||
ret = compat_table_info(private, &tmp);
|
ret = compat_table_info(private, &tmp);
|
||||||
xt_compat_flush_offsets(AF_INET);
|
xt_compat_flush_offsets(AF_INET);
|
||||||
private = &tmp;
|
private = &tmp;
|
||||||
|
@ -210,7 +210,7 @@ static ctl_table ip_ct_sysctl_table[] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.procname = "ip_conntrack_buckets",
|
.procname = "ip_conntrack_buckets",
|
||||||
.data = &nf_conntrack_htable_size,
|
.data = &init_net.ct.htable_size,
|
||||||
.maxlen = sizeof(unsigned int),
|
.maxlen = sizeof(unsigned int),
|
||||||
.mode = 0444,
|
.mode = 0444,
|
||||||
.proc_handler = proc_dointvec,
|
.proc_handler = proc_dointvec,
|
||||||
|
@ -32,7 +32,7 @@ static struct hlist_nulls_node *ct_get_first(struct seq_file *seq)
|
|||||||
struct hlist_nulls_node *n;
|
struct hlist_nulls_node *n;
|
||||||
|
|
||||||
for (st->bucket = 0;
|
for (st->bucket = 0;
|
||||||
st->bucket < nf_conntrack_htable_size;
|
st->bucket < net->ct.htable_size;
|
||||||
st->bucket++) {
|
st->bucket++) {
|
||||||
n = rcu_dereference(net->ct.hash[st->bucket].first);
|
n = rcu_dereference(net->ct.hash[st->bucket].first);
|
||||||
if (!is_a_nulls(n))
|
if (!is_a_nulls(n))
|
||||||
@ -50,7 +50,7 @@ static struct hlist_nulls_node *ct_get_next(struct seq_file *seq,
|
|||||||
head = rcu_dereference(head->next);
|
head = rcu_dereference(head->next);
|
||||||
while (is_a_nulls(head)) {
|
while (is_a_nulls(head)) {
|
||||||
if (likely(get_nulls_value(head) == st->bucket)) {
|
if (likely(get_nulls_value(head) == st->bucket)) {
|
||||||
if (++st->bucket >= nf_conntrack_htable_size)
|
if (++st->bucket >= net->ct.htable_size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
head = rcu_dereference(net->ct.hash[st->bucket].first);
|
head = rcu_dereference(net->ct.hash[st->bucket].first);
|
||||||
|
@ -35,9 +35,6 @@ static DEFINE_SPINLOCK(nf_nat_lock);
|
|||||||
|
|
||||||
static struct nf_conntrack_l3proto *l3proto __read_mostly;
|
static struct nf_conntrack_l3proto *l3proto __read_mostly;
|
||||||
|
|
||||||
/* Calculated at init based on memory size */
|
|
||||||
static unsigned int nf_nat_htable_size __read_mostly;
|
|
||||||
|
|
||||||
#define MAX_IP_NAT_PROTO 256
|
#define MAX_IP_NAT_PROTO 256
|
||||||
static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO]
|
static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO]
|
||||||
__read_mostly;
|
__read_mostly;
|
||||||
@ -72,7 +69,7 @@ EXPORT_SYMBOL_GPL(nf_nat_proto_put);
|
|||||||
|
|
||||||
/* We keep an extra hash for each conntrack, for fast searching. */
|
/* We keep an extra hash for each conntrack, for fast searching. */
|
||||||
static inline unsigned int
|
static inline unsigned int
|
||||||
hash_by_src(const struct nf_conntrack_tuple *tuple)
|
hash_by_src(const struct net *net, const struct nf_conntrack_tuple *tuple)
|
||||||
{
|
{
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
|
|
||||||
@ -80,7 +77,7 @@ hash_by_src(const struct nf_conntrack_tuple *tuple)
|
|||||||
hash = jhash_3words((__force u32)tuple->src.u3.ip,
|
hash = jhash_3words((__force u32)tuple->src.u3.ip,
|
||||||
(__force u32)tuple->src.u.all,
|
(__force u32)tuple->src.u.all,
|
||||||
tuple->dst.protonum, 0);
|
tuple->dst.protonum, 0);
|
||||||
return ((u64)hash * nf_nat_htable_size) >> 32;
|
return ((u64)hash * net->ipv4.nat_htable_size) >> 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is this tuple already taken? (not by us) */
|
/* Is this tuple already taken? (not by us) */
|
||||||
@ -147,7 +144,7 @@ find_appropriate_src(struct net *net,
|
|||||||
struct nf_conntrack_tuple *result,
|
struct nf_conntrack_tuple *result,
|
||||||
const struct nf_nat_range *range)
|
const struct nf_nat_range *range)
|
||||||
{
|
{
|
||||||
unsigned int h = hash_by_src(tuple);
|
unsigned int h = hash_by_src(net, tuple);
|
||||||
const struct nf_conn_nat *nat;
|
const struct nf_conn_nat *nat;
|
||||||
const struct nf_conn *ct;
|
const struct nf_conn *ct;
|
||||||
const struct hlist_node *n;
|
const struct hlist_node *n;
|
||||||
@ -330,7 +327,7 @@ nf_nat_setup_info(struct nf_conn *ct,
|
|||||||
if (have_to_hash) {
|
if (have_to_hash) {
|
||||||
unsigned int srchash;
|
unsigned int srchash;
|
||||||
|
|
||||||
srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
srchash = hash_by_src(net, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
||||||
spin_lock_bh(&nf_nat_lock);
|
spin_lock_bh(&nf_nat_lock);
|
||||||
/* nf_conntrack_alter_reply might re-allocate exntension aera */
|
/* nf_conntrack_alter_reply might re-allocate exntension aera */
|
||||||
nat = nfct_nat(ct);
|
nat = nfct_nat(ct);
|
||||||
@ -679,8 +676,10 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct,
|
|||||||
|
|
||||||
static int __net_init nf_nat_net_init(struct net *net)
|
static int __net_init nf_nat_net_init(struct net *net)
|
||||||
{
|
{
|
||||||
net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
|
/* Leave them the same for the moment. */
|
||||||
&net->ipv4.nat_vmalloced, 0);
|
net->ipv4.nat_htable_size = net->ct.htable_size;
|
||||||
|
net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&net->ipv4.nat_htable_size,
|
||||||
|
&net->ipv4.nat_vmalloced, 0);
|
||||||
if (!net->ipv4.nat_bysource)
|
if (!net->ipv4.nat_bysource)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
return 0;
|
return 0;
|
||||||
@ -703,7 +702,7 @@ static void __net_exit nf_nat_net_exit(struct net *net)
|
|||||||
nf_ct_iterate_cleanup(net, &clean_nat, NULL);
|
nf_ct_iterate_cleanup(net, &clean_nat, NULL);
|
||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced,
|
nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced,
|
||||||
nf_nat_htable_size);
|
net->ipv4.nat_htable_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pernet_operations nf_nat_net_ops = {
|
static struct pernet_operations nf_nat_net_ops = {
|
||||||
@ -724,9 +723,6 @@ static int __init nf_nat_init(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Leave them the same for the moment. */
|
|
||||||
nf_nat_htable_size = nf_conntrack_htable_size;
|
|
||||||
|
|
||||||
ret = register_pernet_subsys(&nf_nat_net_ops);
|
ret = register_pernet_subsys(&nf_nat_net_ops);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto cleanup_extend;
|
goto cleanup_extend;
|
||||||
|
@ -1164,10 +1164,10 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
|
|||||||
if (t && !IS_ERR(t)) {
|
if (t && !IS_ERR(t)) {
|
||||||
struct ip6t_getinfo info;
|
struct ip6t_getinfo info;
|
||||||
const struct xt_table_info *private = t->private;
|
const struct xt_table_info *private = t->private;
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
|
struct xt_table_info tmp;
|
||||||
|
|
||||||
if (compat) {
|
if (compat) {
|
||||||
struct xt_table_info tmp;
|
|
||||||
ret = compat_table_info(private, &tmp);
|
ret = compat_table_info(private, &tmp);
|
||||||
xt_compat_flush_offsets(AF_INET6);
|
xt_compat_flush_offsets(AF_INET6);
|
||||||
private = &tmp;
|
private = &tmp;
|
||||||
|
@ -698,15 +698,18 @@ dev_irnet_ioctl(
|
|||||||
|
|
||||||
/* Query PPP channel and unit number */
|
/* Query PPP channel and unit number */
|
||||||
case PPPIOCGCHAN:
|
case PPPIOCGCHAN:
|
||||||
|
lock_kernel();
|
||||||
if(ap->ppp_open && !put_user(ppp_channel_index(&ap->chan),
|
if(ap->ppp_open && !put_user(ppp_channel_index(&ap->chan),
|
||||||
(int __user *)argp))
|
(int __user *)argp))
|
||||||
err = 0;
|
err = 0;
|
||||||
|
unlock_kernel();
|
||||||
break;
|
break;
|
||||||
case PPPIOCGUNIT:
|
case PPPIOCGUNIT:
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
if(ap->ppp_open && !put_user(ppp_unit_number(&ap->chan),
|
if(ap->ppp_open && !put_user(ppp_unit_number(&ap->chan),
|
||||||
(int __user *)argp))
|
(int __user *)argp))
|
||||||
err = 0;
|
err = 0;
|
||||||
|
unlock_kernel();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* All these ioctls can be passed both directly and from ppp_generic,
|
/* All these ioctls can be passed both directly and from ppp_generic,
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/socket.h>
|
#include <linux/socket.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
#include <linux/nsproxy.h>
|
||||||
#include <linux/rculist_nulls.h>
|
#include <linux/rculist_nulls.h>
|
||||||
|
|
||||||
#include <net/netfilter/nf_conntrack.h>
|
#include <net/netfilter/nf_conntrack.h>
|
||||||
@ -63,8 +64,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_max);
|
|||||||
struct nf_conn nf_conntrack_untracked __read_mostly;
|
struct nf_conn nf_conntrack_untracked __read_mostly;
|
||||||
EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
|
EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
|
||||||
|
|
||||||
static struct kmem_cache *nf_conntrack_cachep __read_mostly;
|
|
||||||
|
|
||||||
static int nf_conntrack_hash_rnd_initted;
|
static int nf_conntrack_hash_rnd_initted;
|
||||||
static unsigned int nf_conntrack_hash_rnd;
|
static unsigned int nf_conntrack_hash_rnd;
|
||||||
|
|
||||||
@ -86,9 +85,10 @@ static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
|
|||||||
return ((u64)h * size) >> 32;
|
return ((u64)h * size) >> 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
|
static inline u_int32_t hash_conntrack(const struct net *net,
|
||||||
|
const struct nf_conntrack_tuple *tuple)
|
||||||
{
|
{
|
||||||
return __hash_conntrack(tuple, nf_conntrack_htable_size,
|
return __hash_conntrack(tuple, net->ct.htable_size,
|
||||||
nf_conntrack_hash_rnd);
|
nf_conntrack_hash_rnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ __nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple)
|
|||||||
{
|
{
|
||||||
struct nf_conntrack_tuple_hash *h;
|
struct nf_conntrack_tuple_hash *h;
|
||||||
struct hlist_nulls_node *n;
|
struct hlist_nulls_node *n;
|
||||||
unsigned int hash = hash_conntrack(tuple);
|
unsigned int hash = hash_conntrack(net, tuple);
|
||||||
|
|
||||||
/* Disable BHs the entire time since we normally need to disable them
|
/* Disable BHs the entire time since we normally need to disable them
|
||||||
* at least once for the stats anyway.
|
* at least once for the stats anyway.
|
||||||
@ -366,10 +366,11 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
|
|||||||
|
|
||||||
void nf_conntrack_hash_insert(struct nf_conn *ct)
|
void nf_conntrack_hash_insert(struct nf_conn *ct)
|
||||||
{
|
{
|
||||||
|
struct net *net = nf_ct_net(ct);
|
||||||
unsigned int hash, repl_hash;
|
unsigned int hash, repl_hash;
|
||||||
|
|
||||||
hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
hash = hash_conntrack(net, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
||||||
repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
|
repl_hash = hash_conntrack(net, &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
|
||||||
|
|
||||||
__nf_conntrack_hash_insert(ct, hash, repl_hash);
|
__nf_conntrack_hash_insert(ct, hash, repl_hash);
|
||||||
}
|
}
|
||||||
@ -397,8 +398,8 @@ __nf_conntrack_confirm(struct sk_buff *skb)
|
|||||||
if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
|
if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
hash = hash_conntrack(net, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
||||||
repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
|
repl_hash = hash_conntrack(net, &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
|
||||||
|
|
||||||
/* We're not in hash table, and we refuse to set up related
|
/* We're not in hash table, and we refuse to set up related
|
||||||
connections for unconfirmed conns. But packet copies and
|
connections for unconfirmed conns. But packet copies and
|
||||||
@ -468,7 +469,7 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
|
|||||||
struct net *net = nf_ct_net(ignored_conntrack);
|
struct net *net = nf_ct_net(ignored_conntrack);
|
||||||
struct nf_conntrack_tuple_hash *h;
|
struct nf_conntrack_tuple_hash *h;
|
||||||
struct hlist_nulls_node *n;
|
struct hlist_nulls_node *n;
|
||||||
unsigned int hash = hash_conntrack(tuple);
|
unsigned int hash = hash_conntrack(net, tuple);
|
||||||
|
|
||||||
/* Disable BHs the entire time since we need to disable them at
|
/* Disable BHs the entire time since we need to disable them at
|
||||||
* least once for the stats anyway.
|
* least once for the stats anyway.
|
||||||
@ -503,7 +504,7 @@ static noinline int early_drop(struct net *net, unsigned int hash)
|
|||||||
int dropped = 0;
|
int dropped = 0;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
for (i = 0; i < nf_conntrack_htable_size; i++) {
|
for (i = 0; i < net->ct.htable_size; i++) {
|
||||||
hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash],
|
hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash],
|
||||||
hnnode) {
|
hnnode) {
|
||||||
tmp = nf_ct_tuplehash_to_ctrack(h);
|
tmp = nf_ct_tuplehash_to_ctrack(h);
|
||||||
@ -523,7 +524,7 @@ static noinline int early_drop(struct net *net, unsigned int hash)
|
|||||||
if (cnt >= NF_CT_EVICTION_RANGE)
|
if (cnt >= NF_CT_EVICTION_RANGE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
hash = (hash + 1) % nf_conntrack_htable_size;
|
hash = (hash + 1) % net->ct.htable_size;
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
@ -557,7 +558,7 @@ struct nf_conn *nf_conntrack_alloc(struct net *net,
|
|||||||
|
|
||||||
if (nf_conntrack_max &&
|
if (nf_conntrack_max &&
|
||||||
unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) {
|
unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) {
|
||||||
unsigned int hash = hash_conntrack(orig);
|
unsigned int hash = hash_conntrack(net, orig);
|
||||||
if (!early_drop(net, hash)) {
|
if (!early_drop(net, hash)) {
|
||||||
atomic_dec(&net->ct.count);
|
atomic_dec(&net->ct.count);
|
||||||
if (net_ratelimit())
|
if (net_ratelimit())
|
||||||
@ -572,7 +573,7 @@ struct nf_conn *nf_conntrack_alloc(struct net *net,
|
|||||||
* Do not use kmem_cache_zalloc(), as this cache uses
|
* Do not use kmem_cache_zalloc(), as this cache uses
|
||||||
* SLAB_DESTROY_BY_RCU.
|
* SLAB_DESTROY_BY_RCU.
|
||||||
*/
|
*/
|
||||||
ct = kmem_cache_alloc(nf_conntrack_cachep, gfp);
|
ct = kmem_cache_alloc(net->ct.nf_conntrack_cachep, gfp);
|
||||||
if (ct == NULL) {
|
if (ct == NULL) {
|
||||||
pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
|
pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
|
||||||
atomic_dec(&net->ct.count);
|
atomic_dec(&net->ct.count);
|
||||||
@ -611,7 +612,7 @@ void nf_conntrack_free(struct nf_conn *ct)
|
|||||||
nf_ct_ext_destroy(ct);
|
nf_ct_ext_destroy(ct);
|
||||||
atomic_dec(&net->ct.count);
|
atomic_dec(&net->ct.count);
|
||||||
nf_ct_ext_free(ct);
|
nf_ct_ext_free(ct);
|
||||||
kmem_cache_free(nf_conntrack_cachep, ct);
|
kmem_cache_free(net->ct.nf_conntrack_cachep, ct);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(nf_conntrack_free);
|
EXPORT_SYMBOL_GPL(nf_conntrack_free);
|
||||||
|
|
||||||
@ -1014,7 +1015,7 @@ get_next_corpse(struct net *net, int (*iter)(struct nf_conn *i, void *data),
|
|||||||
struct hlist_nulls_node *n;
|
struct hlist_nulls_node *n;
|
||||||
|
|
||||||
spin_lock_bh(&nf_conntrack_lock);
|
spin_lock_bh(&nf_conntrack_lock);
|
||||||
for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
|
for (; *bucket < net->ct.htable_size; (*bucket)++) {
|
||||||
hlist_nulls_for_each_entry(h, n, &net->ct.hash[*bucket], hnnode) {
|
hlist_nulls_for_each_entry(h, n, &net->ct.hash[*bucket], hnnode) {
|
||||||
ct = nf_ct_tuplehash_to_ctrack(h);
|
ct = nf_ct_tuplehash_to_ctrack(h);
|
||||||
if (iter(ct, data))
|
if (iter(ct, data))
|
||||||
@ -1113,9 +1114,12 @@ static void nf_ct_release_dying_list(struct net *net)
|
|||||||
|
|
||||||
static void nf_conntrack_cleanup_init_net(void)
|
static void nf_conntrack_cleanup_init_net(void)
|
||||||
{
|
{
|
||||||
|
/* wait until all references to nf_conntrack_untracked are dropped */
|
||||||
|
while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
|
||||||
|
schedule();
|
||||||
|
|
||||||
nf_conntrack_helper_fini();
|
nf_conntrack_helper_fini();
|
||||||
nf_conntrack_proto_fini();
|
nf_conntrack_proto_fini();
|
||||||
kmem_cache_destroy(nf_conntrack_cachep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nf_conntrack_cleanup_net(struct net *net)
|
static void nf_conntrack_cleanup_net(struct net *net)
|
||||||
@ -1127,15 +1131,14 @@ static void nf_conntrack_cleanup_net(struct net *net)
|
|||||||
schedule();
|
schedule();
|
||||||
goto i_see_dead_people;
|
goto i_see_dead_people;
|
||||||
}
|
}
|
||||||
/* wait until all references to nf_conntrack_untracked are dropped */
|
|
||||||
while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
|
|
||||||
schedule();
|
|
||||||
|
|
||||||
nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
|
nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
|
||||||
nf_conntrack_htable_size);
|
net->ct.htable_size);
|
||||||
nf_conntrack_ecache_fini(net);
|
nf_conntrack_ecache_fini(net);
|
||||||
nf_conntrack_acct_fini(net);
|
nf_conntrack_acct_fini(net);
|
||||||
nf_conntrack_expect_fini(net);
|
nf_conntrack_expect_fini(net);
|
||||||
|
kmem_cache_destroy(net->ct.nf_conntrack_cachep);
|
||||||
|
kfree(net->ct.slabname);
|
||||||
free_percpu(net->ct.stat);
|
free_percpu(net->ct.stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1190,10 +1193,12 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
|
|||||||
{
|
{
|
||||||
int i, bucket, vmalloced, old_vmalloced;
|
int i, bucket, vmalloced, old_vmalloced;
|
||||||
unsigned int hashsize, old_size;
|
unsigned int hashsize, old_size;
|
||||||
int rnd;
|
|
||||||
struct hlist_nulls_head *hash, *old_hash;
|
struct hlist_nulls_head *hash, *old_hash;
|
||||||
struct nf_conntrack_tuple_hash *h;
|
struct nf_conntrack_tuple_hash *h;
|
||||||
|
|
||||||
|
if (current->nsproxy->net_ns != &init_net)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
/* On boot, we can set this without any fancy locking. */
|
/* On boot, we can set this without any fancy locking. */
|
||||||
if (!nf_conntrack_htable_size)
|
if (!nf_conntrack_htable_size)
|
||||||
return param_set_uint(val, kp);
|
return param_set_uint(val, kp);
|
||||||
@ -1206,33 +1211,29 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
|
|||||||
if (!hash)
|
if (!hash)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* We have to rehahs for the new table anyway, so we also can
|
|
||||||
* use a newrandom seed */
|
|
||||||
get_random_bytes(&rnd, sizeof(rnd));
|
|
||||||
|
|
||||||
/* Lookups in the old hash might happen in parallel, which means we
|
/* Lookups in the old hash might happen in parallel, which means we
|
||||||
* might get false negatives during connection lookup. New connections
|
* might get false negatives during connection lookup. New connections
|
||||||
* created because of a false negative won't make it into the hash
|
* created because of a false negative won't make it into the hash
|
||||||
* though since that required taking the lock.
|
* though since that required taking the lock.
|
||||||
*/
|
*/
|
||||||
spin_lock_bh(&nf_conntrack_lock);
|
spin_lock_bh(&nf_conntrack_lock);
|
||||||
for (i = 0; i < nf_conntrack_htable_size; i++) {
|
for (i = 0; i < init_net.ct.htable_size; i++) {
|
||||||
while (!hlist_nulls_empty(&init_net.ct.hash[i])) {
|
while (!hlist_nulls_empty(&init_net.ct.hash[i])) {
|
||||||
h = hlist_nulls_entry(init_net.ct.hash[i].first,
|
h = hlist_nulls_entry(init_net.ct.hash[i].first,
|
||||||
struct nf_conntrack_tuple_hash, hnnode);
|
struct nf_conntrack_tuple_hash, hnnode);
|
||||||
hlist_nulls_del_rcu(&h->hnnode);
|
hlist_nulls_del_rcu(&h->hnnode);
|
||||||
bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
|
bucket = __hash_conntrack(&h->tuple, hashsize,
|
||||||
|
nf_conntrack_hash_rnd);
|
||||||
hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]);
|
hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
old_size = nf_conntrack_htable_size;
|
old_size = init_net.ct.htable_size;
|
||||||
old_vmalloced = init_net.ct.hash_vmalloc;
|
old_vmalloced = init_net.ct.hash_vmalloc;
|
||||||
old_hash = init_net.ct.hash;
|
old_hash = init_net.ct.hash;
|
||||||
|
|
||||||
nf_conntrack_htable_size = hashsize;
|
init_net.ct.htable_size = nf_conntrack_htable_size = hashsize;
|
||||||
init_net.ct.hash_vmalloc = vmalloced;
|
init_net.ct.hash_vmalloc = vmalloced;
|
||||||
init_net.ct.hash = hash;
|
init_net.ct.hash = hash;
|
||||||
nf_conntrack_hash_rnd = rnd;
|
|
||||||
spin_unlock_bh(&nf_conntrack_lock);
|
spin_unlock_bh(&nf_conntrack_lock);
|
||||||
|
|
||||||
nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);
|
nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);
|
||||||
@ -1271,15 +1272,6 @@ static int nf_conntrack_init_init_net(void)
|
|||||||
NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
|
NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
|
||||||
nf_conntrack_max);
|
nf_conntrack_max);
|
||||||
|
|
||||||
nf_conntrack_cachep = kmem_cache_create("nf_conntrack",
|
|
||||||
sizeof(struct nf_conn),
|
|
||||||
0, SLAB_DESTROY_BY_RCU, NULL);
|
|
||||||
if (!nf_conntrack_cachep) {
|
|
||||||
printk(KERN_ERR "Unable to create nf_conn slab cache\n");
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err_cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nf_conntrack_proto_init();
|
ret = nf_conntrack_proto_init();
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_proto;
|
goto err_proto;
|
||||||
@ -1288,13 +1280,19 @@ static int nf_conntrack_init_init_net(void)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_helper;
|
goto err_helper;
|
||||||
|
|
||||||
|
/* Set up fake conntrack: to never be deleted, not in any hashes */
|
||||||
|
#ifdef CONFIG_NET_NS
|
||||||
|
nf_conntrack_untracked.ct_net = &init_net;
|
||||||
|
#endif
|
||||||
|
atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
|
||||||
|
/* - and look it like as a confirmed connection */
|
||||||
|
set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_helper:
|
err_helper:
|
||||||
nf_conntrack_proto_fini();
|
nf_conntrack_proto_fini();
|
||||||
err_proto:
|
err_proto:
|
||||||
kmem_cache_destroy(nf_conntrack_cachep);
|
|
||||||
err_cache:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1316,7 +1314,24 @@ static int nf_conntrack_init_net(struct net *net)
|
|||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err_stat;
|
goto err_stat;
|
||||||
}
|
}
|
||||||
net->ct.hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
|
|
||||||
|
net->ct.slabname = kasprintf(GFP_KERNEL, "nf_conntrack_%p", net);
|
||||||
|
if (!net->ct.slabname) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_slabname;
|
||||||
|
}
|
||||||
|
|
||||||
|
net->ct.nf_conntrack_cachep = kmem_cache_create(net->ct.slabname,
|
||||||
|
sizeof(struct nf_conn), 0,
|
||||||
|
SLAB_DESTROY_BY_RCU, NULL);
|
||||||
|
if (!net->ct.nf_conntrack_cachep) {
|
||||||
|
printk(KERN_ERR "Unable to create nf_conn slab cache\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
net->ct.htable_size = nf_conntrack_htable_size;
|
||||||
|
net->ct.hash = nf_ct_alloc_hashtable(&net->ct.htable_size,
|
||||||
&net->ct.hash_vmalloc, 1);
|
&net->ct.hash_vmalloc, 1);
|
||||||
if (!net->ct.hash) {
|
if (!net->ct.hash) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
@ -1333,15 +1348,6 @@ static int nf_conntrack_init_net(struct net *net)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_ecache;
|
goto err_ecache;
|
||||||
|
|
||||||
/* Set up fake conntrack:
|
|
||||||
- to never be deleted, not in any hashes */
|
|
||||||
#ifdef CONFIG_NET_NS
|
|
||||||
nf_conntrack_untracked.ct_net = &init_net;
|
|
||||||
#endif
|
|
||||||
atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
|
|
||||||
/* - and look it like as a confirmed connection */
|
|
||||||
set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_ecache:
|
err_ecache:
|
||||||
@ -1350,8 +1356,12 @@ err_acct:
|
|||||||
nf_conntrack_expect_fini(net);
|
nf_conntrack_expect_fini(net);
|
||||||
err_expect:
|
err_expect:
|
||||||
nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
|
nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
|
||||||
nf_conntrack_htable_size);
|
net->ct.htable_size);
|
||||||
err_hash:
|
err_hash:
|
||||||
|
kmem_cache_destroy(net->ct.nf_conntrack_cachep);
|
||||||
|
err_cache:
|
||||||
|
kfree(net->ct.slabname);
|
||||||
|
err_slabname:
|
||||||
free_percpu(net->ct.stat);
|
free_percpu(net->ct.stat);
|
||||||
err_stat:
|
err_stat:
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -569,7 +569,7 @@ static void exp_proc_remove(struct net *net)
|
|||||||
#endif /* CONFIG_PROC_FS */
|
#endif /* CONFIG_PROC_FS */
|
||||||
}
|
}
|
||||||
|
|
||||||
module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600);
|
module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0400);
|
||||||
|
|
||||||
int nf_conntrack_expect_init(struct net *net)
|
int nf_conntrack_expect_init(struct net *net)
|
||||||
{
|
{
|
||||||
@ -577,7 +577,7 @@ int nf_conntrack_expect_init(struct net *net)
|
|||||||
|
|
||||||
if (net_eq(net, &init_net)) {
|
if (net_eq(net, &init_net)) {
|
||||||
if (!nf_ct_expect_hsize) {
|
if (!nf_ct_expect_hsize) {
|
||||||
nf_ct_expect_hsize = nf_conntrack_htable_size / 256;
|
nf_ct_expect_hsize = net->ct.htable_size / 256;
|
||||||
if (!nf_ct_expect_hsize)
|
if (!nf_ct_expect_hsize)
|
||||||
nf_ct_expect_hsize = 1;
|
nf_ct_expect_hsize = 1;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
|
|||||||
/* Get rid of expecteds, set helpers to NULL. */
|
/* Get rid of expecteds, set helpers to NULL. */
|
||||||
hlist_nulls_for_each_entry(h, nn, &net->ct.unconfirmed, hnnode)
|
hlist_nulls_for_each_entry(h, nn, &net->ct.unconfirmed, hnnode)
|
||||||
unhelp(h, me);
|
unhelp(h, me);
|
||||||
for (i = 0; i < nf_conntrack_htable_size; i++) {
|
for (i = 0; i < net->ct.htable_size; i++) {
|
||||||
hlist_nulls_for_each_entry(h, nn, &net->ct.hash[i], hnnode)
|
hlist_nulls_for_each_entry(h, nn, &net->ct.hash[i], hnnode)
|
||||||
unhelp(h, me);
|
unhelp(h, me);
|
||||||
}
|
}
|
||||||
|
@ -594,7 +594,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
|
|||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
last = (struct nf_conn *)cb->args[1];
|
last = (struct nf_conn *)cb->args[1];
|
||||||
for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
|
for (; cb->args[0] < init_net.ct.htable_size; cb->args[0]++) {
|
||||||
restart:
|
restart:
|
||||||
hlist_nulls_for_each_entry_rcu(h, n, &init_net.ct.hash[cb->args[0]],
|
hlist_nulls_for_each_entry_rcu(h, n, &init_net.ct.hash[cb->args[0]],
|
||||||
hnnode) {
|
hnnode) {
|
||||||
|
@ -51,7 +51,7 @@ static struct hlist_nulls_node *ct_get_first(struct seq_file *seq)
|
|||||||
struct hlist_nulls_node *n;
|
struct hlist_nulls_node *n;
|
||||||
|
|
||||||
for (st->bucket = 0;
|
for (st->bucket = 0;
|
||||||
st->bucket < nf_conntrack_htable_size;
|
st->bucket < net->ct.htable_size;
|
||||||
st->bucket++) {
|
st->bucket++) {
|
||||||
n = rcu_dereference(net->ct.hash[st->bucket].first);
|
n = rcu_dereference(net->ct.hash[st->bucket].first);
|
||||||
if (!is_a_nulls(n))
|
if (!is_a_nulls(n))
|
||||||
@ -69,7 +69,7 @@ static struct hlist_nulls_node *ct_get_next(struct seq_file *seq,
|
|||||||
head = rcu_dereference(head->next);
|
head = rcu_dereference(head->next);
|
||||||
while (is_a_nulls(head)) {
|
while (is_a_nulls(head)) {
|
||||||
if (likely(get_nulls_value(head) == st->bucket)) {
|
if (likely(get_nulls_value(head) == st->bucket)) {
|
||||||
if (++st->bucket >= nf_conntrack_htable_size)
|
if (++st->bucket >= net->ct.htable_size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
head = rcu_dereference(net->ct.hash[st->bucket].first);
|
head = rcu_dereference(net->ct.hash[st->bucket].first);
|
||||||
@ -355,7 +355,7 @@ static ctl_table nf_ct_sysctl_table[] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.procname = "nf_conntrack_buckets",
|
.procname = "nf_conntrack_buckets",
|
||||||
.data = &nf_conntrack_htable_size,
|
.data = &init_net.ct.htable_size,
|
||||||
.maxlen = sizeof(unsigned int),
|
.maxlen = sizeof(unsigned int),
|
||||||
.mode = 0444,
|
.mode = 0444,
|
||||||
.proc_handler = proc_dointvec,
|
.proc_handler = proc_dointvec,
|
||||||
@ -421,6 +421,7 @@ static int nf_conntrack_standalone_init_sysctl(struct net *net)
|
|||||||
goto out_kmemdup;
|
goto out_kmemdup;
|
||||||
|
|
||||||
table[1].data = &net->ct.count;
|
table[1].data = &net->ct.count;
|
||||||
|
table[2].data = &net->ct.htable_size;
|
||||||
table[3].data = &net->ct.sysctl_checksum;
|
table[3].data = &net->ct.sysctl_checksum;
|
||||||
table[4].data = &net->ct.sysctl_log_invalid;
|
table[4].data = &net->ct.sysctl_log_invalid;
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ config NET_ACT_POLICE
|
|||||||
module.
|
module.
|
||||||
|
|
||||||
To compile this code as a module, choose M here: the
|
To compile this code as a module, choose M here: the
|
||||||
module will be called police.
|
module will be called act_police.
|
||||||
|
|
||||||
config NET_ACT_GACT
|
config NET_ACT_GACT
|
||||||
tristate "Generic actions"
|
tristate "Generic actions"
|
||||||
@ -443,7 +443,7 @@ config NET_ACT_GACT
|
|||||||
accepting packets.
|
accepting packets.
|
||||||
|
|
||||||
To compile this code as a module, choose M here: the
|
To compile this code as a module, choose M here: the
|
||||||
module will be called gact.
|
module will be called act_gact.
|
||||||
|
|
||||||
config GACT_PROB
|
config GACT_PROB
|
||||||
bool "Probability support"
|
bool "Probability support"
|
||||||
@ -459,7 +459,7 @@ config NET_ACT_MIRRED
|
|||||||
other devices.
|
other devices.
|
||||||
|
|
||||||
To compile this code as a module, choose M here: the
|
To compile this code as a module, choose M here: the
|
||||||
module will be called mirred.
|
module will be called act_mirred.
|
||||||
|
|
||||||
config NET_ACT_IPT
|
config NET_ACT_IPT
|
||||||
tristate "IPtables targets"
|
tristate "IPtables targets"
|
||||||
@ -469,7 +469,7 @@ config NET_ACT_IPT
|
|||||||
classification.
|
classification.
|
||||||
|
|
||||||
To compile this code as a module, choose M here: the
|
To compile this code as a module, choose M here: the
|
||||||
module will be called ipt.
|
module will be called act_ipt.
|
||||||
|
|
||||||
config NET_ACT_NAT
|
config NET_ACT_NAT
|
||||||
tristate "Stateless NAT"
|
tristate "Stateless NAT"
|
||||||
@ -479,7 +479,7 @@ config NET_ACT_NAT
|
|||||||
netfilter for NAT unless you know what you are doing.
|
netfilter for NAT unless you know what you are doing.
|
||||||
|
|
||||||
To compile this code as a module, choose M here: the
|
To compile this code as a module, choose M here: the
|
||||||
module will be called nat.
|
module will be called act_nat.
|
||||||
|
|
||||||
config NET_ACT_PEDIT
|
config NET_ACT_PEDIT
|
||||||
tristate "Packet Editing"
|
tristate "Packet Editing"
|
||||||
@ -488,7 +488,7 @@ config NET_ACT_PEDIT
|
|||||||
Say Y here if you want to mangle the content of packets.
|
Say Y here if you want to mangle the content of packets.
|
||||||
|
|
||||||
To compile this code as a module, choose M here: the
|
To compile this code as a module, choose M here: the
|
||||||
module will be called pedit.
|
module will be called act_pedit.
|
||||||
|
|
||||||
config NET_ACT_SIMP
|
config NET_ACT_SIMP
|
||||||
tristate "Simple Example (Debug)"
|
tristate "Simple Example (Debug)"
|
||||||
@ -502,7 +502,7 @@ config NET_ACT_SIMP
|
|||||||
If unsure, say N.
|
If unsure, say N.
|
||||||
|
|
||||||
To compile this code as a module, choose M here: the
|
To compile this code as a module, choose M here: the
|
||||||
module will be called simple.
|
module will be called act_simple.
|
||||||
|
|
||||||
config NET_ACT_SKBEDIT
|
config NET_ACT_SKBEDIT
|
||||||
tristate "SKB Editing"
|
tristate "SKB Editing"
|
||||||
@ -513,7 +513,7 @@ config NET_ACT_SKBEDIT
|
|||||||
If unsure, say N.
|
If unsure, say N.
|
||||||
|
|
||||||
To compile this code as a module, choose M here: the
|
To compile this code as a module, choose M here: the
|
||||||
module will be called skbedit.
|
module will be called act_skbedit.
|
||||||
|
|
||||||
config NET_CLS_IND
|
config NET_CLS_IND
|
||||||
bool "Incoming device classification"
|
bool "Incoming device classification"
|
||||||
|
Loading…
Reference in New Issue
Block a user