mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 19:56:18 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: netfilter: nf_conntrack_sctp: fix sparse warnings netfilter: nf_nat_sip: c= is optional for session netfilter: xt_TCPMSS: collapse tcpmss_reverse_mtu{4,6} into one function netfilter: nfnetlink_log: send complete hardware header netfilter: xt_time: fix time's time_mt()'s use of do_div() netfilter: accounting rework: ct_extend + 64bit counters (v4) netlink: add NLA_PUT_BE64 macro netfilter: nf_nat_core: eliminate useless find_appropriate_src for IP_NAT_RANGE_PROTO_RANDOM hdlcdrv: Fix CRC calculation. Revert "pkt_sched: Make default qdisc nonshared-multiqueue safe." net: In __netif_schedule() use WARN_ON instead of BUG_ON net: Improve simple_tx_hash(). pkt_sched: Remove unused variable skb in dev_deactivate_queue function. sunhme: Remove stop/wake TX queue calls in set-multicast-list handler. ucc_geth: do not touch net queue in adjust_link phylib callback gianfar: do not touch net queue in adjust_link phylib callback atl1: Do not wake queue before queue has been started.
This commit is contained in:
commit
e89970aa93
30 changed files with 412 additions and 185 deletions
|
@ -336,3 +336,13 @@ When: After the only user (hal) has seen a release with the patches
|
||||||
Why: Over 1K .text/.data size reduction, data is available in other
|
Why: Over 1K .text/.data size reduction, data is available in other
|
||||||
ways (ioctls)
|
ways (ioctls)
|
||||||
Who: Johannes Berg <johannes@sipsolutions.net>
|
Who: Johannes Berg <johannes@sipsolutions.net>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: CONFIG_NF_CT_ACCT
|
||||||
|
When: 2.6.29
|
||||||
|
Why: Accounting can now be enabled/disabled without kernel recompilation.
|
||||||
|
Currently used only to set a default value for a feature that is also
|
||||||
|
controlled by a kernel/module/sysfs/sysctl parameter.
|
||||||
|
Who: Krzysztof Piotr Oledzki <ole@ans.pl>
|
||||||
|
|
||||||
|
|
|
@ -1279,6 +1279,13 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
This usage is only documented in each driver source
|
This usage is only documented in each driver source
|
||||||
file if at all.
|
file if at all.
|
||||||
|
|
||||||
|
nf_conntrack.acct=
|
||||||
|
[NETFILTER] Enable connection tracking flow accounting
|
||||||
|
0 to disable accounting
|
||||||
|
1 to enable accounting
|
||||||
|
Default value depends on CONFIG_NF_CT_ACCT that is
|
||||||
|
going to be removed in 2.6.29.
|
||||||
|
|
||||||
nfsaddrs= [NFS]
|
nfsaddrs= [NFS]
|
||||||
See Documentation/filesystems/nfsroot.txt.
|
See Documentation/filesystems/nfsroot.txt.
|
||||||
|
|
||||||
|
|
|
@ -1308,7 +1308,6 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
|
||||||
dev_info(&adapter->pdev->dev, "link is down\n");
|
dev_info(&adapter->pdev->dev, "link is down\n");
|
||||||
adapter->link_speed = SPEED_0;
|
adapter->link_speed = SPEED_0;
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
netif_stop_queue(netdev);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1358,7 +1357,6 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
|
||||||
if (!netif_carrier_ok(netdev)) {
|
if (!netif_carrier_ok(netdev)) {
|
||||||
/* Link down -> Up */
|
/* Link down -> Up */
|
||||||
netif_carrier_on(netdev);
|
netif_carrier_on(netdev);
|
||||||
netif_wake_queue(netdev);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2627,6 +2625,7 @@ static s32 atl1_up(struct atl1_adapter *adapter)
|
||||||
mod_timer(&adapter->watchdog_timer, jiffies);
|
mod_timer(&adapter->watchdog_timer, jiffies);
|
||||||
atlx_irq_enable(adapter);
|
atlx_irq_enable(adapter);
|
||||||
atl1_check_link(adapter);
|
atl1_check_link(adapter);
|
||||||
|
netif_start_queue(netdev);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_up:
|
err_up:
|
||||||
|
|
|
@ -1725,7 +1725,6 @@ static void adjust_link(struct net_device *dev)
|
||||||
if (!priv->oldlink) {
|
if (!priv->oldlink) {
|
||||||
new_state = 1;
|
new_state = 1;
|
||||||
priv->oldlink = 1;
|
priv->oldlink = 1;
|
||||||
netif_tx_schedule_all(dev);
|
|
||||||
}
|
}
|
||||||
} else if (priv->oldlink) {
|
} else if (priv->oldlink) {
|
||||||
new_state = 1;
|
new_state = 1;
|
||||||
|
|
|
@ -88,6 +88,7 @@
|
||||||
static inline void append_crc_ccitt(unsigned char *buffer, int len)
|
static inline void append_crc_ccitt(unsigned char *buffer, int len)
|
||||||
{
|
{
|
||||||
unsigned int crc = crc_ccitt(0xffff, buffer, len) ^ 0xffff;
|
unsigned int crc = crc_ccitt(0xffff, buffer, len) ^ 0xffff;
|
||||||
|
buffer += len;
|
||||||
*buffer++ = crc;
|
*buffer++ = crc;
|
||||||
*buffer++ = crc >> 8;
|
*buffer++ = crc >> 8;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2377,8 +2377,6 @@ static void happy_meal_set_multicast(struct net_device *dev)
|
||||||
|
|
||||||
spin_lock_irq(&hp->happy_lock);
|
spin_lock_irq(&hp->happy_lock);
|
||||||
|
|
||||||
netif_stop_queue(dev);
|
|
||||||
|
|
||||||
if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
|
if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
|
||||||
hme_write32(hp, bregs + BMAC_HTABLE0, 0xffff);
|
hme_write32(hp, bregs + BMAC_HTABLE0, 0xffff);
|
||||||
hme_write32(hp, bregs + BMAC_HTABLE1, 0xffff);
|
hme_write32(hp, bregs + BMAC_HTABLE1, 0xffff);
|
||||||
|
@ -2410,8 +2408,6 @@ static void happy_meal_set_multicast(struct net_device *dev)
|
||||||
hme_write32(hp, bregs + BMAC_HTABLE3, hash_table[3]);
|
hme_write32(hp, bregs + BMAC_HTABLE3, hash_table[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
netif_wake_queue(dev);
|
|
||||||
|
|
||||||
spin_unlock_irq(&hp->happy_lock);
|
spin_unlock_irq(&hp->happy_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1588,7 +1588,6 @@ static void adjust_link(struct net_device *dev)
|
||||||
if (!ugeth->oldlink) {
|
if (!ugeth->oldlink) {
|
||||||
new_state = 1;
|
new_state = 1;
|
||||||
ugeth->oldlink = 1;
|
ugeth->oldlink = 1;
|
||||||
netif_tx_schedule_all(dev);
|
|
||||||
}
|
}
|
||||||
} else if (ugeth->oldlink) {
|
} else if (ugeth->oldlink) {
|
||||||
new_state = 1;
|
new_state = 1;
|
||||||
|
|
|
@ -122,7 +122,7 @@ enum ip_conntrack_events
|
||||||
IPCT_NATINFO_BIT = 10,
|
IPCT_NATINFO_BIT = 10,
|
||||||
IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
|
IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
|
||||||
|
|
||||||
/* Counter highest bit has been set */
|
/* Counter highest bit has been set, unused */
|
||||||
IPCT_COUNTER_FILLING_BIT = 11,
|
IPCT_COUNTER_FILLING_BIT = 11,
|
||||||
IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
|
IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
|
||||||
|
|
||||||
|
@ -145,12 +145,6 @@ enum ip_conntrack_expect_events {
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
struct ip_conntrack_counter
|
|
||||||
{
|
|
||||||
u_int32_t packets;
|
|
||||||
u_int32_t bytes;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ip_conntrack_stat
|
struct ip_conntrack_stat
|
||||||
{
|
{
|
||||||
unsigned int searched;
|
unsigned int searched;
|
||||||
|
|
|
@ -115,10 +115,10 @@ enum ctattr_protoinfo_sctp {
|
||||||
|
|
||||||
enum ctattr_counters {
|
enum ctattr_counters {
|
||||||
CTA_COUNTERS_UNSPEC,
|
CTA_COUNTERS_UNSPEC,
|
||||||
CTA_COUNTERS_PACKETS, /* old 64bit counters */
|
CTA_COUNTERS_PACKETS, /* 64bit counters */
|
||||||
CTA_COUNTERS_BYTES, /* old 64bit counters */
|
CTA_COUNTERS_BYTES, /* 64bit counters */
|
||||||
CTA_COUNTERS32_PACKETS,
|
CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */
|
||||||
CTA_COUNTERS32_BYTES,
|
CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */
|
||||||
__CTA_COUNTERS_MAX
|
__CTA_COUNTERS_MAX
|
||||||
};
|
};
|
||||||
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
|
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
|
||||||
|
|
|
@ -48,6 +48,9 @@ enum nfulnl_attr_type {
|
||||||
NFULA_SEQ, /* instance-local sequence number */
|
NFULA_SEQ, /* instance-local sequence number */
|
||||||
NFULA_SEQ_GLOBAL, /* global sequence number */
|
NFULA_SEQ_GLOBAL, /* global sequence number */
|
||||||
NFULA_GID, /* group id of socket */
|
NFULA_GID, /* group id of socket */
|
||||||
|
NFULA_HWTYPE, /* hardware type */
|
||||||
|
NFULA_HWHEADER, /* hardware header */
|
||||||
|
NFULA_HWLEN, /* hardware header length */
|
||||||
|
|
||||||
__NFULA_MAX
|
__NFULA_MAX
|
||||||
};
|
};
|
||||||
|
|
|
@ -88,7 +88,6 @@ struct nf_conn_help {
|
||||||
u8 expecting[NF_CT_MAX_EXPECT_CLASSES];
|
u8 expecting[NF_CT_MAX_EXPECT_CLASSES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
|
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
|
||||||
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
|
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
|
||||||
|
|
||||||
|
@ -111,11 +110,6 @@ struct nf_conn
|
||||||
/* Timer function; drops refcnt when it goes off. */
|
/* Timer function; drops refcnt when it goes off. */
|
||||||
struct timer_list timeout;
|
struct timer_list timeout;
|
||||||
|
|
||||||
#ifdef CONFIG_NF_CT_ACCT
|
|
||||||
/* Accounting Information (same cache line as other written members) */
|
|
||||||
struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_NF_CONNTRACK_MARK)
|
#if defined(CONFIG_NF_CONNTRACK_MARK)
|
||||||
u_int32_t mark;
|
u_int32_t mark;
|
||||||
#endif
|
#endif
|
||||||
|
|
51
include/net/netfilter/nf_conntrack_acct.h
Normal file
51
include/net/netfilter/nf_conntrack_acct.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* (C) 2008 Krzysztof Piotr Oledzki <ole@ans.pl>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NF_CONNTRACK_ACCT_H
|
||||||
|
#define _NF_CONNTRACK_ACCT_H
|
||||||
|
#include <linux/netfilter/nf_conntrack_common.h>
|
||||||
|
#include <linux/netfilter/nf_conntrack_tuple_common.h>
|
||||||
|
#include <net/netfilter/nf_conntrack.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_extend.h>
|
||||||
|
|
||||||
|
struct nf_conn_counter {
|
||||||
|
u_int64_t packets;
|
||||||
|
u_int64_t bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int nf_ct_acct;
|
||||||
|
|
||||||
|
static inline
|
||||||
|
struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct)
|
||||||
|
{
|
||||||
|
return nf_ct_ext_find(ct, NF_CT_EXT_ACCT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp)
|
||||||
|
{
|
||||||
|
struct nf_conn_counter *acct;
|
||||||
|
|
||||||
|
if (!nf_ct_acct)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
acct = nf_ct_ext_add(ct, NF_CT_EXT_ACCT, gfp);
|
||||||
|
if (!acct)
|
||||||
|
pr_debug("failed to add accounting extension area");
|
||||||
|
|
||||||
|
|
||||||
|
return acct;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern unsigned int
|
||||||
|
seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir);
|
||||||
|
|
||||||
|
extern int nf_conntrack_acct_init(void);
|
||||||
|
extern void nf_conntrack_acct_fini(void);
|
||||||
|
|
||||||
|
#endif /* _NF_CONNTRACK_ACCT_H */
|
|
@ -7,11 +7,13 @@ enum nf_ct_ext_id
|
||||||
{
|
{
|
||||||
NF_CT_EXT_HELPER,
|
NF_CT_EXT_HELPER,
|
||||||
NF_CT_EXT_NAT,
|
NF_CT_EXT_NAT,
|
||||||
|
NF_CT_EXT_ACCT,
|
||||||
NF_CT_EXT_NUM,
|
NF_CT_EXT_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NF_CT_EXT_HELPER_TYPE struct nf_conn_help
|
#define NF_CT_EXT_HELPER_TYPE struct nf_conn_help
|
||||||
#define NF_CT_EXT_NAT_TYPE struct nf_conn_nat
|
#define NF_CT_EXT_NAT_TYPE struct nf_conn_nat
|
||||||
|
#define NF_CT_EXT_ACCT_TYPE struct nf_conn_counter
|
||||||
|
|
||||||
/* Extensions: optional stuff which isn't permanently in struct. */
|
/* Extensions: optional stuff which isn't permanently in struct. */
|
||||||
struct nf_ct_ext {
|
struct nf_ct_ext {
|
||||||
|
|
|
@ -896,6 +896,9 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
|
||||||
#define NLA_PUT_U64(skb, attrtype, value) \
|
#define NLA_PUT_U64(skb, attrtype, value) \
|
||||||
NLA_PUT_TYPE(skb, u64, attrtype, value)
|
NLA_PUT_TYPE(skb, u64, attrtype, value)
|
||||||
|
|
||||||
|
#define NLA_PUT_BE64(skb, attrtype, value) \
|
||||||
|
NLA_PUT_TYPE(skb, __be64, attrtype, value)
|
||||||
|
|
||||||
#define NLA_PUT_STRING(skb, attrtype, value) \
|
#define NLA_PUT_STRING(skb, attrtype, value) \
|
||||||
NLA_PUT(skb, attrtype, strlen(value) + 1, value)
|
NLA_PUT(skb, attrtype, strlen(value) + 1, value)
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,8 @@
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/ipv6.h>
|
#include <linux/ipv6.h>
|
||||||
#include <linux/in.h>
|
#include <linux/in.h>
|
||||||
|
#include <linux/jhash.h>
|
||||||
|
#include <linux/random.h>
|
||||||
|
|
||||||
#include "net-sysfs.h"
|
#include "net-sysfs.h"
|
||||||
|
|
||||||
|
@ -1325,7 +1327,8 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
void __netif_schedule(struct Qdisc *q)
|
void __netif_schedule(struct Qdisc *q)
|
||||||
{
|
{
|
||||||
BUG_ON(q == &noop_qdisc);
|
if (WARN_ON_ONCE(q == &noop_qdisc))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) {
|
if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) {
|
||||||
struct softnet_data *sd;
|
struct softnet_data *sd;
|
||||||
|
@ -1668,34 +1671,37 @@ out_kfree_skb:
|
||||||
* --BLG
|
* --BLG
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static u32 simple_tx_hashrnd;
|
||||||
|
static int simple_tx_hashrnd_initialized = 0;
|
||||||
|
|
||||||
static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
|
static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
u32 *addr, *ports, hash, ihl;
|
u32 addr1, addr2, ports;
|
||||||
|
u32 hash, ihl;
|
||||||
u8 ip_proto;
|
u8 ip_proto;
|
||||||
int alen;
|
|
||||||
|
if (unlikely(!simple_tx_hashrnd_initialized)) {
|
||||||
|
get_random_bytes(&simple_tx_hashrnd, 4);
|
||||||
|
simple_tx_hashrnd_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
switch (skb->protocol) {
|
switch (skb->protocol) {
|
||||||
case __constant_htons(ETH_P_IP):
|
case __constant_htons(ETH_P_IP):
|
||||||
ip_proto = ip_hdr(skb)->protocol;
|
ip_proto = ip_hdr(skb)->protocol;
|
||||||
addr = &ip_hdr(skb)->saddr;
|
addr1 = ip_hdr(skb)->saddr;
|
||||||
|
addr2 = ip_hdr(skb)->daddr;
|
||||||
ihl = ip_hdr(skb)->ihl;
|
ihl = ip_hdr(skb)->ihl;
|
||||||
alen = 2;
|
|
||||||
break;
|
break;
|
||||||
case __constant_htons(ETH_P_IPV6):
|
case __constant_htons(ETH_P_IPV6):
|
||||||
ip_proto = ipv6_hdr(skb)->nexthdr;
|
ip_proto = ipv6_hdr(skb)->nexthdr;
|
||||||
addr = &ipv6_hdr(skb)->saddr.s6_addr32[0];
|
addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
|
||||||
|
addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
|
||||||
ihl = (40 >> 2);
|
ihl = (40 >> 2);
|
||||||
alen = 8;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ports = (u32 *) (skb_network_header(skb) + (ihl * 4));
|
|
||||||
|
|
||||||
hash = 0;
|
|
||||||
while (alen--)
|
|
||||||
hash ^= *addr++;
|
|
||||||
|
|
||||||
switch (ip_proto) {
|
switch (ip_proto) {
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
|
@ -1705,14 +1711,17 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
|
||||||
case IPPROTO_AH:
|
case IPPROTO_AH:
|
||||||
case IPPROTO_SCTP:
|
case IPPROTO_SCTP:
|
||||||
case IPPROTO_UDPLITE:
|
case IPPROTO_UDPLITE:
|
||||||
hash ^= *ports;
|
ports = *((u32 *) (skb_network_header(skb) + (ihl * 4)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
ports = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash % dev->real_num_tx_queues;
|
hash = jhash_3words(addr1, addr2, ports, simple_tx_hashrnd);
|
||||||
|
|
||||||
|
return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct netdev_queue *dev_pick_tx(struct net_device *dev,
|
static struct netdev_queue *dev_pick_tx(struct net_device *dev,
|
||||||
|
|
|
@ -18,19 +18,7 @@
|
||||||
#include <net/netfilter/nf_conntrack_l3proto.h>
|
#include <net/netfilter/nf_conntrack_l3proto.h>
|
||||||
#include <net/netfilter/nf_conntrack_l4proto.h>
|
#include <net/netfilter/nf_conntrack_l4proto.h>
|
||||||
#include <net/netfilter/nf_conntrack_expect.h>
|
#include <net/netfilter/nf_conntrack_expect.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_acct.h>
|
||||||
#ifdef CONFIG_NF_CT_ACCT
|
|
||||||
static unsigned int
|
|
||||||
seq_print_counters(struct seq_file *s,
|
|
||||||
const struct ip_conntrack_counter *counter)
|
|
||||||
{
|
|
||||||
return seq_printf(s, "packets=%llu bytes=%llu ",
|
|
||||||
(unsigned long long)counter->packets,
|
|
||||||
(unsigned long long)counter->bytes);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define seq_print_counters(x, y) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ct_iter_state {
|
struct ct_iter_state {
|
||||||
unsigned int bucket;
|
unsigned int bucket;
|
||||||
|
@ -127,7 +115,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
|
||||||
l3proto, l4proto))
|
l3proto, l4proto))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL]))
|
if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
|
if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
|
||||||
|
@ -138,7 +126,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
|
||||||
l3proto, l4proto))
|
l3proto, l4proto))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY]))
|
if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
if (test_bit(IPS_ASSURED_BIT, &ct->status))
|
if (test_bit(IPS_ASSURED_BIT, &ct->status))
|
||||||
|
|
|
@ -240,12 +240,12 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||||
This is only required for source (ie. NAT/masq) mappings.
|
This is only required for source (ie. NAT/masq) mappings.
|
||||||
So far, we don't do local source mappings, so multiple
|
So far, we don't do local source mappings, so multiple
|
||||||
manips not an issue. */
|
manips not an issue. */
|
||||||
if (maniptype == IP_NAT_MANIP_SRC) {
|
if (maniptype == IP_NAT_MANIP_SRC &&
|
||||||
|
!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
|
||||||
if (find_appropriate_src(orig_tuple, tuple, range)) {
|
if (find_appropriate_src(orig_tuple, tuple, range)) {
|
||||||
pr_debug("get_unique_tuple: Found current src map\n");
|
pr_debug("get_unique_tuple: Found current src map\n");
|
||||||
if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
|
if (!nf_nat_used_tuple(tuple, ct))
|
||||||
if (!nf_nat_used_tuple(tuple, ct))
|
return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -318,11 +318,11 @@ static int mangle_content_len(struct sk_buff *skb,
|
||||||
buffer, buflen);
|
buffer, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
|
static int mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
|
||||||
unsigned int dataoff, unsigned int *datalen,
|
unsigned int dataoff, unsigned int *datalen,
|
||||||
enum sdp_header_types type,
|
enum sdp_header_types type,
|
||||||
enum sdp_header_types term,
|
enum sdp_header_types term,
|
||||||
char *buffer, int buflen)
|
char *buffer, int buflen)
|
||||||
{
|
{
|
||||||
enum ip_conntrack_info ctinfo;
|
enum ip_conntrack_info ctinfo;
|
||||||
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
|
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
|
||||||
|
@ -330,9 +330,9 @@ static unsigned mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
|
||||||
|
|
||||||
if (ct_sip_get_sdp_header(ct, *dptr, dataoff, *datalen, type, term,
|
if (ct_sip_get_sdp_header(ct, *dptr, dataoff, *datalen, type, term,
|
||||||
&matchoff, &matchlen) <= 0)
|
&matchoff, &matchlen) <= 0)
|
||||||
return 0;
|
return -ENOENT;
|
||||||
return mangle_packet(skb, dptr, datalen, matchoff, matchlen,
|
return mangle_packet(skb, dptr, datalen, matchoff, matchlen,
|
||||||
buffer, buflen);
|
buffer, buflen) ? 0 : -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
|
static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
|
||||||
|
@ -346,8 +346,8 @@ static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
|
||||||
unsigned int buflen;
|
unsigned int buflen;
|
||||||
|
|
||||||
buflen = sprintf(buffer, NIPQUAD_FMT, NIPQUAD(addr->ip));
|
buflen = sprintf(buffer, NIPQUAD_FMT, NIPQUAD(addr->ip));
|
||||||
if (!mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term,
|
if (mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term,
|
||||||
buffer, buflen))
|
buffer, buflen))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return mangle_content_len(skb, dptr, datalen);
|
return mangle_content_len(skb, dptr, datalen);
|
||||||
|
@ -381,15 +381,27 @@ static unsigned int ip_nat_sdp_session(struct sk_buff *skb, const char **dptr,
|
||||||
|
|
||||||
/* Mangle session description owner and contact addresses */
|
/* Mangle session description owner and contact addresses */
|
||||||
buflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(addr->ip));
|
buflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(addr->ip));
|
||||||
if (!mangle_sdp_packet(skb, dptr, dataoff, datalen,
|
if (mangle_sdp_packet(skb, dptr, dataoff, datalen,
|
||||||
SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA,
|
SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA,
|
||||||
buffer, buflen))
|
buffer, buflen))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!mangle_sdp_packet(skb, dptr, dataoff, datalen,
|
switch (mangle_sdp_packet(skb, dptr, dataoff, datalen,
|
||||||
SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA,
|
SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA,
|
||||||
buffer, buflen))
|
buffer, buflen)) {
|
||||||
|
case 0:
|
||||||
|
/*
|
||||||
|
* RFC 2327:
|
||||||
|
*
|
||||||
|
* Session description
|
||||||
|
*
|
||||||
|
* c=* (connection information - not required if included in all media)
|
||||||
|
*/
|
||||||
|
case -ENOENT:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return mangle_content_len(skb, dptr, datalen);
|
return mangle_content_len(skb, dptr, datalen);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,15 @@ config NF_CT_ACCT
|
||||||
Those counters can be used for flow-based accounting or the
|
Those counters can be used for flow-based accounting or the
|
||||||
`connbytes' match.
|
`connbytes' match.
|
||||||
|
|
||||||
|
Please note that currently this option only sets a default state.
|
||||||
|
You may change it at boot time with nf_conntrack.acct=0/1 kernel
|
||||||
|
paramater or by loading the nf_conntrack module with acct=0/1.
|
||||||
|
|
||||||
|
You may also disable/enable it on a running system with:
|
||||||
|
sysctl net.netfilter.nf_conntrack_acct=0/1
|
||||||
|
|
||||||
|
This option will be removed in 2.6.29.
|
||||||
|
|
||||||
If unsure, say `N'.
|
If unsure, say `N'.
|
||||||
|
|
||||||
config NF_CONNTRACK_MARK
|
config NF_CONNTRACK_MARK
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o
|
netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o
|
||||||
|
|
||||||
nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o
|
nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o nf_conntrack_acct.o
|
||||||
nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
|
nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
|
||||||
|
|
||||||
obj-$(CONFIG_NETFILTER) = netfilter.o
|
obj-$(CONFIG_NETFILTER) = netfilter.o
|
||||||
|
|
104
net/netfilter/nf_conntrack_acct.c
Normal file
104
net/netfilter/nf_conntrack_acct.c
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/* Accouting handling for netfilter. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (C) 2008 Krzysztof Piotr Oledzki <ole@ans.pl>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/netfilter.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/moduleparam.h>
|
||||||
|
|
||||||
|
#include <net/netfilter/nf_conntrack.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_extend.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_acct.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_NF_CT_ACCT
|
||||||
|
#define NF_CT_ACCT_DEFAULT 1
|
||||||
|
#else
|
||||||
|
#define NF_CT_ACCT_DEFAULT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT;
|
||||||
|
EXPORT_SYMBOL_GPL(nf_ct_acct);
|
||||||
|
|
||||||
|
module_param_named(acct, nf_ct_acct, bool, 0644);
|
||||||
|
MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting.");
|
||||||
|
|
||||||
|
#ifdef CONFIG_SYSCTL
|
||||||
|
static struct ctl_table_header *acct_sysctl_header;
|
||||||
|
static struct ctl_table acct_sysctl_table[] = {
|
||||||
|
{
|
||||||
|
.ctl_name = CTL_UNNUMBERED,
|
||||||
|
.procname = "nf_conntrack_acct",
|
||||||
|
.data = &nf_ct_acct,
|
||||||
|
.maxlen = sizeof(unsigned int),
|
||||||
|
.mode = 0644,
|
||||||
|
.proc_handler = &proc_dointvec,
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_SYSCTL */
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir)
|
||||||
|
{
|
||||||
|
struct nf_conn_counter *acct;
|
||||||
|
|
||||||
|
acct = nf_conn_acct_find(ct);
|
||||||
|
if (!acct)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return seq_printf(s, "packets=%llu bytes=%llu ",
|
||||||
|
(unsigned long long)acct[dir].packets,
|
||||||
|
(unsigned long long)acct[dir].bytes);
|
||||||
|
};
|
||||||
|
EXPORT_SYMBOL_GPL(seq_print_acct);
|
||||||
|
|
||||||
|
static struct nf_ct_ext_type acct_extend __read_mostly = {
|
||||||
|
.len = sizeof(struct nf_conn_counter[IP_CT_DIR_MAX]),
|
||||||
|
.align = __alignof__(struct nf_conn_counter[IP_CT_DIR_MAX]),
|
||||||
|
.id = NF_CT_EXT_ACCT,
|
||||||
|
};
|
||||||
|
|
||||||
|
int nf_conntrack_acct_init(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#ifdef CONFIG_NF_CT_ACCT
|
||||||
|
printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n");
|
||||||
|
printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n");
|
||||||
|
printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = nf_ct_extend_register(&acct_extend);
|
||||||
|
if (ret < 0) {
|
||||||
|
printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SYSCTL
|
||||||
|
acct_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path,
|
||||||
|
acct_sysctl_table);
|
||||||
|
|
||||||
|
if (!acct_sysctl_header) {
|
||||||
|
nf_ct_extend_unregister(&acct_extend);
|
||||||
|
|
||||||
|
printk(KERN_ERR "nf_conntrack_acct: can't register to sysctl.\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nf_conntrack_acct_fini(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SYSCTL
|
||||||
|
unregister_sysctl_table(acct_sysctl_header);
|
||||||
|
#endif
|
||||||
|
nf_ct_extend_unregister(&acct_extend);
|
||||||
|
}
|
|
@ -37,6 +37,7 @@
|
||||||
#include <net/netfilter/nf_conntrack_helper.h>
|
#include <net/netfilter/nf_conntrack_helper.h>
|
||||||
#include <net/netfilter/nf_conntrack_core.h>
|
#include <net/netfilter/nf_conntrack_core.h>
|
||||||
#include <net/netfilter/nf_conntrack_extend.h>
|
#include <net/netfilter/nf_conntrack_extend.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_acct.h>
|
||||||
|
|
||||||
#define NF_CONNTRACK_VERSION "0.5.0"
|
#define NF_CONNTRACK_VERSION "0.5.0"
|
||||||
|
|
||||||
|
@ -555,6 +556,8 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nf_ct_acct_ext_add(ct, GFP_ATOMIC);
|
||||||
|
|
||||||
spin_lock_bh(&nf_conntrack_lock);
|
spin_lock_bh(&nf_conntrack_lock);
|
||||||
exp = nf_ct_find_expectation(tuple);
|
exp = nf_ct_find_expectation(tuple);
|
||||||
if (exp) {
|
if (exp) {
|
||||||
|
@ -828,17 +831,16 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
|
||||||
}
|
}
|
||||||
|
|
||||||
acct:
|
acct:
|
||||||
#ifdef CONFIG_NF_CT_ACCT
|
|
||||||
if (do_acct) {
|
if (do_acct) {
|
||||||
ct->counters[CTINFO2DIR(ctinfo)].packets++;
|
struct nf_conn_counter *acct;
|
||||||
ct->counters[CTINFO2DIR(ctinfo)].bytes +=
|
|
||||||
skb->len - skb_network_offset(skb);
|
|
||||||
|
|
||||||
if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
|
acct = nf_conn_acct_find(ct);
|
||||||
|| (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
|
if (acct) {
|
||||||
event |= IPCT_COUNTER_FILLING;
|
acct[CTINFO2DIR(ctinfo)].packets++;
|
||||||
|
acct[CTINFO2DIR(ctinfo)].bytes +=
|
||||||
|
skb->len - skb_network_offset(skb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
spin_unlock_bh(&nf_conntrack_lock);
|
spin_unlock_bh(&nf_conntrack_lock);
|
||||||
|
|
||||||
|
@ -853,15 +855,19 @@ bool __nf_ct_kill_acct(struct nf_conn *ct,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
int do_acct)
|
int do_acct)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NF_CT_ACCT
|
|
||||||
if (do_acct) {
|
if (do_acct) {
|
||||||
|
struct nf_conn_counter *acct;
|
||||||
|
|
||||||
spin_lock_bh(&nf_conntrack_lock);
|
spin_lock_bh(&nf_conntrack_lock);
|
||||||
ct->counters[CTINFO2DIR(ctinfo)].packets++;
|
acct = nf_conn_acct_find(ct);
|
||||||
ct->counters[CTINFO2DIR(ctinfo)].bytes +=
|
if (acct) {
|
||||||
skb->len - skb_network_offset(skb);
|
acct[CTINFO2DIR(ctinfo)].packets++;
|
||||||
|
acct[CTINFO2DIR(ctinfo)].bytes +=
|
||||||
|
skb->len - skb_network_offset(skb);
|
||||||
|
}
|
||||||
spin_unlock_bh(&nf_conntrack_lock);
|
spin_unlock_bh(&nf_conntrack_lock);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (del_timer(&ct->timeout)) {
|
if (del_timer(&ct->timeout)) {
|
||||||
ct->timeout.function((unsigned long)ct);
|
ct->timeout.function((unsigned long)ct);
|
||||||
return true;
|
return true;
|
||||||
|
@ -1029,6 +1035,7 @@ void nf_conntrack_cleanup(void)
|
||||||
nf_conntrack_proto_fini();
|
nf_conntrack_proto_fini();
|
||||||
nf_conntrack_helper_fini();
|
nf_conntrack_helper_fini();
|
||||||
nf_conntrack_expect_fini();
|
nf_conntrack_expect_fini();
|
||||||
|
nf_conntrack_acct_fini();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced)
|
struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced)
|
||||||
|
@ -1168,6 +1175,10 @@ int __init nf_conntrack_init(void)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out_fini_expect;
|
goto out_fini_expect;
|
||||||
|
|
||||||
|
ret = nf_conntrack_acct_init();
|
||||||
|
if (ret < 0)
|
||||||
|
goto out_fini_helper;
|
||||||
|
|
||||||
/* For use by REJECT target */
|
/* For use by REJECT target */
|
||||||
rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
|
rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
|
||||||
rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
|
rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
|
||||||
|
@ -1180,6 +1191,8 @@ int __init nf_conntrack_init(void)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
out_fini_helper:
|
||||||
|
nf_conntrack_helper_fini();
|
||||||
out_fini_expect:
|
out_fini_expect:
|
||||||
nf_conntrack_expect_fini();
|
nf_conntrack_expect_fini();
|
||||||
out_fini_proto:
|
out_fini_proto:
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <net/netfilter/nf_conntrack_l3proto.h>
|
#include <net/netfilter/nf_conntrack_l3proto.h>
|
||||||
#include <net/netfilter/nf_conntrack_l4proto.h>
|
#include <net/netfilter/nf_conntrack_l4proto.h>
|
||||||
#include <net/netfilter/nf_conntrack_tuple.h>
|
#include <net/netfilter/nf_conntrack_tuple.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_acct.h>
|
||||||
#ifdef CONFIG_NF_NAT_NEEDED
|
#ifdef CONFIG_NF_NAT_NEEDED
|
||||||
#include <net/netfilter/nf_nat_core.h>
|
#include <net/netfilter/nf_nat_core.h>
|
||||||
#include <net/netfilter/nf_nat_protocol.h>
|
#include <net/netfilter/nf_nat_protocol.h>
|
||||||
|
@ -206,22 +207,26 @@ nla_put_failure:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NF_CT_ACCT
|
|
||||||
static int
|
static int
|
||||||
ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
|
ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
|
||||||
enum ip_conntrack_dir dir)
|
enum ip_conntrack_dir dir)
|
||||||
{
|
{
|
||||||
enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
|
enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
|
||||||
struct nlattr *nest_count;
|
struct nlattr *nest_count;
|
||||||
|
const struct nf_conn_counter *acct;
|
||||||
|
|
||||||
|
acct = nf_conn_acct_find(ct);
|
||||||
|
if (!acct)
|
||||||
|
return 0;
|
||||||
|
|
||||||
nest_count = nla_nest_start(skb, type | NLA_F_NESTED);
|
nest_count = nla_nest_start(skb, type | NLA_F_NESTED);
|
||||||
if (!nest_count)
|
if (!nest_count)
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
NLA_PUT_BE32(skb, CTA_COUNTERS32_PACKETS,
|
NLA_PUT_BE64(skb, CTA_COUNTERS_PACKETS,
|
||||||
htonl(ct->counters[dir].packets));
|
cpu_to_be64(acct[dir].packets));
|
||||||
NLA_PUT_BE32(skb, CTA_COUNTERS32_BYTES,
|
NLA_PUT_BE64(skb, CTA_COUNTERS_BYTES,
|
||||||
htonl(ct->counters[dir].bytes));
|
cpu_to_be64(acct[dir].bytes));
|
||||||
|
|
||||||
nla_nest_end(skb, nest_count);
|
nla_nest_end(skb, nest_count);
|
||||||
|
|
||||||
|
@ -230,9 +235,6 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#define ctnetlink_dump_counters(a, b, c) (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||||
static inline int
|
static inline int
|
||||||
|
@ -501,11 +503,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (events & IPCT_COUNTER_FILLING &&
|
|
||||||
(ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
|
|
||||||
ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0))
|
|
||||||
goto nla_put_failure;
|
|
||||||
|
|
||||||
if (events & IPCT_RELATED &&
|
if (events & IPCT_RELATED &&
|
||||||
ctnetlink_dump_master(skb, ct) < 0)
|
ctnetlink_dump_master(skb, ct) < 0)
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
@ -576,11 +573,15 @@ restart:
|
||||||
cb->args[1] = (unsigned long)ct;
|
cb->args[1] = (unsigned long)ct;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_NF_CT_ACCT
|
|
||||||
if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) ==
|
if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) ==
|
||||||
IPCTNL_MSG_CT_GET_CTRZERO)
|
IPCTNL_MSG_CT_GET_CTRZERO) {
|
||||||
memset(&ct->counters, 0, sizeof(ct->counters));
|
struct nf_conn_counter *acct;
|
||||||
#endif
|
|
||||||
|
acct = nf_conn_acct_find(ct);
|
||||||
|
if (acct)
|
||||||
|
memset(acct, 0, sizeof(struct nf_conn_counter[IP_CT_DIR_MAX]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cb->args[1]) {
|
if (cb->args[1]) {
|
||||||
cb->args[1] = 0;
|
cb->args[1] = 0;
|
||||||
|
@ -832,14 +833,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
|
||||||
u_int8_t u3 = nfmsg->nfgen_family;
|
u_int8_t u3 = nfmsg->nfgen_family;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (nlh->nlmsg_flags & NLM_F_DUMP) {
|
if (nlh->nlmsg_flags & NLM_F_DUMP)
|
||||||
#ifndef CONFIG_NF_CT_ACCT
|
|
||||||
if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO)
|
|
||||||
return -ENOTSUPP;
|
|
||||||
#endif
|
|
||||||
return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table,
|
return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table,
|
||||||
ctnetlink_done);
|
ctnetlink_done);
|
||||||
}
|
|
||||||
|
|
||||||
if (cda[CTA_TUPLE_ORIG])
|
if (cda[CTA_TUPLE_ORIG])
|
||||||
err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
|
err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
|
||||||
|
@ -1152,6 +1148,8 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nf_ct_acct_ext_add(ct, GFP_KERNEL);
|
||||||
|
|
||||||
#if defined(CONFIG_NF_CONNTRACK_MARK)
|
#if defined(CONFIG_NF_CONNTRACK_MARK)
|
||||||
if (cda[CTA_MARK])
|
if (cda[CTA_MARK])
|
||||||
ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
|
ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
|
||||||
|
|
|
@ -482,11 +482,11 @@ static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
|
||||||
|
|
||||||
NLA_PUT_BE32(skb,
|
NLA_PUT_BE32(skb,
|
||||||
CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
|
CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
|
||||||
htonl(ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]));
|
ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]);
|
||||||
|
|
||||||
NLA_PUT_BE32(skb,
|
NLA_PUT_BE32(skb,
|
||||||
CTA_PROTOINFO_SCTP_VTAG_REPLY,
|
CTA_PROTOINFO_SCTP_VTAG_REPLY,
|
||||||
htonl(ct->proto.sctp.vtag[IP_CT_DIR_REPLY]));
|
ct->proto.sctp.vtag[IP_CT_DIR_REPLY]);
|
||||||
|
|
||||||
read_unlock_bh(&sctp_lock);
|
read_unlock_bh(&sctp_lock);
|
||||||
|
|
||||||
|
@ -530,9 +530,9 @@ static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
|
||||||
write_lock_bh(&sctp_lock);
|
write_lock_bh(&sctp_lock);
|
||||||
ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
|
ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
|
||||||
ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
|
ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
|
||||||
ntohl(nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]));
|
nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
|
||||||
ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
|
ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
|
||||||
ntohl(nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]));
|
nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
|
||||||
write_unlock_bh(&sctp_lock);
|
write_unlock_bh(&sctp_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <net/netfilter/nf_conntrack_l4proto.h>
|
#include <net/netfilter/nf_conntrack_l4proto.h>
|
||||||
#include <net/netfilter/nf_conntrack_expect.h>
|
#include <net/netfilter/nf_conntrack_expect.h>
|
||||||
#include <net/netfilter/nf_conntrack_helper.h>
|
#include <net/netfilter/nf_conntrack_helper.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_acct.h>
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
@ -38,19 +39,6 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(print_tuple);
|
EXPORT_SYMBOL_GPL(print_tuple);
|
||||||
|
|
||||||
#ifdef CONFIG_NF_CT_ACCT
|
|
||||||
static unsigned int
|
|
||||||
seq_print_counters(struct seq_file *s,
|
|
||||||
const struct ip_conntrack_counter *counter)
|
|
||||||
{
|
|
||||||
return seq_printf(s, "packets=%llu bytes=%llu ",
|
|
||||||
(unsigned long long)counter->packets,
|
|
||||||
(unsigned long long)counter->bytes);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define seq_print_counters(x, y) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ct_iter_state {
|
struct ct_iter_state {
|
||||||
unsigned int bucket;
|
unsigned int bucket;
|
||||||
};
|
};
|
||||||
|
@ -146,7 +134,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
|
||||||
l3proto, l4proto))
|
l3proto, l4proto))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL]))
|
if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
|
if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
|
||||||
|
@ -157,7 +145,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
|
||||||
l3proto, l4proto))
|
l3proto, l4proto))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY]))
|
if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
if (test_bit(IPS_ASSURED_BIT, &ct->status))
|
if (test_bit(IPS_ASSURED_BIT, &ct->status))
|
||||||
|
|
|
@ -453,6 +453,14 @@ __build_packet_message(struct nfulnl_instance *inst,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (indev && skb_mac_header_was_set(skb)) {
|
||||||
|
NLA_PUT_BE16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type));
|
||||||
|
NLA_PUT_BE16(inst->skb, NFULA_HWLEN,
|
||||||
|
htons(skb->dev->hard_header_len));
|
||||||
|
NLA_PUT(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len,
|
||||||
|
skb_mac_header(skb));
|
||||||
|
}
|
||||||
|
|
||||||
if (skb->tstamp.tv64) {
|
if (skb->tstamp.tv64) {
|
||||||
struct nfulnl_msg_packet_timestamp ts;
|
struct nfulnl_msg_packet_timestamp ts;
|
||||||
struct timeval tv = ktime_to_timeval(skb->tstamp);
|
struct timeval tv = ktime_to_timeval(skb->tstamp);
|
||||||
|
|
|
@ -147,17 +147,21 @@ tcpmss_mangle_packet(struct sk_buff *skb,
|
||||||
return TCPOLEN_MSS;
|
return TCPOLEN_MSS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u_int32_t tcpmss_reverse_mtu4(const struct iphdr *iph)
|
static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb,
|
||||||
|
unsigned int family)
|
||||||
{
|
{
|
||||||
struct flowi fl = {
|
struct flowi fl = {};
|
||||||
.fl4_dst = iph->saddr,
|
|
||||||
};
|
|
||||||
const struct nf_afinfo *ai;
|
const struct nf_afinfo *ai;
|
||||||
struct rtable *rt = NULL;
|
struct rtable *rt = NULL;
|
||||||
u_int32_t mtu = ~0U;
|
u_int32_t mtu = ~0U;
|
||||||
|
|
||||||
|
if (family == PF_INET)
|
||||||
|
fl.fl4_dst = ip_hdr(skb)->saddr;
|
||||||
|
else
|
||||||
|
fl.fl6_dst = ipv6_hdr(skb)->saddr;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
ai = nf_get_afinfo(AF_INET);
|
ai = nf_get_afinfo(family);
|
||||||
if (ai != NULL)
|
if (ai != NULL)
|
||||||
ai->route((struct dst_entry **)&rt, &fl);
|
ai->route((struct dst_entry **)&rt, &fl);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
@ -178,7 +182,8 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
|
||||||
__be16 newlen;
|
__be16 newlen;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu4(iph),
|
ret = tcpmss_mangle_packet(skb, targinfo,
|
||||||
|
tcpmss_reverse_mtu(skb, PF_INET),
|
||||||
iph->ihl * 4,
|
iph->ihl * 4,
|
||||||
sizeof(*iph) + sizeof(struct tcphdr));
|
sizeof(*iph) + sizeof(struct tcphdr));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -193,28 +198,6 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
|
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
|
||||||
static u_int32_t tcpmss_reverse_mtu6(const struct ipv6hdr *iph)
|
|
||||||
{
|
|
||||||
struct flowi fl = {
|
|
||||||
.fl6_dst = iph->saddr,
|
|
||||||
};
|
|
||||||
const struct nf_afinfo *ai;
|
|
||||||
struct rtable *rt = NULL;
|
|
||||||
u_int32_t mtu = ~0U;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
ai = nf_get_afinfo(AF_INET6);
|
|
||||||
if (ai != NULL)
|
|
||||||
ai->route((struct dst_entry **)&rt, &fl);
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
if (rt != NULL) {
|
|
||||||
mtu = dst_mtu(&rt->u.dst);
|
|
||||||
dst_release(&rt->u.dst);
|
|
||||||
}
|
|
||||||
return mtu;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
|
tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
|
||||||
const struct net_device *out, unsigned int hooknum,
|
const struct net_device *out, unsigned int hooknum,
|
||||||
|
@ -229,7 +212,8 @@ tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
|
||||||
tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
|
tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
|
||||||
if (tcphoff < 0)
|
if (tcphoff < 0)
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu6(ipv6h),
|
ret = tcpmss_mangle_packet(skb, targinfo,
|
||||||
|
tcpmss_reverse_mtu(skb, PF_INET6),
|
||||||
tcphoff,
|
tcphoff,
|
||||||
sizeof(*ipv6h) + sizeof(struct tcphdr));
|
sizeof(*ipv6h) + sizeof(struct tcphdr));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <linux/netfilter/x_tables.h>
|
#include <linux/netfilter/x_tables.h>
|
||||||
#include <linux/netfilter/xt_connbytes.h>
|
#include <linux/netfilter/xt_connbytes.h>
|
||||||
#include <net/netfilter/nf_conntrack.h>
|
#include <net/netfilter/nf_conntrack.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_acct.h>
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||||
|
@ -27,12 +28,15 @@ connbytes_mt(const struct sk_buff *skb, const struct net_device *in,
|
||||||
u_int64_t what = 0; /* initialize to make gcc happy */
|
u_int64_t what = 0; /* initialize to make gcc happy */
|
||||||
u_int64_t bytes = 0;
|
u_int64_t bytes = 0;
|
||||||
u_int64_t pkts = 0;
|
u_int64_t pkts = 0;
|
||||||
const struct ip_conntrack_counter *counters;
|
const struct nf_conn_counter *counters;
|
||||||
|
|
||||||
ct = nf_ct_get(skb, &ctinfo);
|
ct = nf_ct_get(skb, &ctinfo);
|
||||||
if (!ct)
|
if (!ct)
|
||||||
return false;
|
return false;
|
||||||
counters = ct->counters;
|
|
||||||
|
counters = nf_conn_acct_find(ct);
|
||||||
|
if (!counters)
|
||||||
|
return false;
|
||||||
|
|
||||||
switch (sinfo->what) {
|
switch (sinfo->what) {
|
||||||
case XT_CONNBYTES_PKTS:
|
case XT_CONNBYTES_PKTS:
|
||||||
|
|
|
@ -173,7 +173,7 @@ time_mt(const struct sk_buff *skb, const struct net_device *in,
|
||||||
__net_timestamp((struct sk_buff *)skb);
|
__net_timestamp((struct sk_buff *)skb);
|
||||||
|
|
||||||
stamp = ktime_to_ns(skb->tstamp);
|
stamp = ktime_to_ns(skb->tstamp);
|
||||||
do_div(stamp, NSEC_PER_SEC);
|
stamp = div_s64(stamp, NSEC_PER_SEC);
|
||||||
|
|
||||||
if (info->flags & XT_TIME_LOCAL_TZ)
|
if (info->flags & XT_TIME_LOCAL_TZ)
|
||||||
/* Adjust for local timezone */
|
/* Adjust for local timezone */
|
||||||
|
|
|
@ -356,44 +356,99 @@ static struct Qdisc noqueue_qdisc = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int fifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
|
static const u8 prio2band[TC_PRIO_MAX+1] =
|
||||||
{
|
{ 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||||
struct sk_buff_head *list = &qdisc->q;
|
|
||||||
|
|
||||||
if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len)
|
/* 3-band FIFO queue: old style, but should be a bit faster than
|
||||||
|
generic prio+fifo combination.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PFIFO_FAST_BANDS 3
|
||||||
|
|
||||||
|
static inline struct sk_buff_head *prio2list(struct sk_buff *skb,
|
||||||
|
struct Qdisc *qdisc)
|
||||||
|
{
|
||||||
|
struct sk_buff_head *list = qdisc_priv(qdisc);
|
||||||
|
return list + prio2band[skb->priority & TC_PRIO_MAX];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
|
||||||
|
{
|
||||||
|
struct sk_buff_head *list = prio2list(skb, qdisc);
|
||||||
|
|
||||||
|
if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
|
||||||
|
qdisc->q.qlen++;
|
||||||
return __qdisc_enqueue_tail(skb, qdisc, list);
|
return __qdisc_enqueue_tail(skb, qdisc, list);
|
||||||
|
}
|
||||||
|
|
||||||
return qdisc_drop(skb, qdisc);
|
return qdisc_drop(skb, qdisc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sk_buff *fifo_fast_dequeue(struct Qdisc* qdisc)
|
static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
|
||||||
{
|
{
|
||||||
struct sk_buff_head *list = &qdisc->q;
|
int prio;
|
||||||
|
struct sk_buff_head *list = qdisc_priv(qdisc);
|
||||||
|
|
||||||
if (!skb_queue_empty(list))
|
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
|
||||||
return __qdisc_dequeue_head(qdisc, list);
|
if (!skb_queue_empty(list + prio)) {
|
||||||
|
qdisc->q.qlen--;
|
||||||
|
return __qdisc_dequeue_head(qdisc, list + prio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
|
static int pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
|
||||||
{
|
{
|
||||||
return __qdisc_requeue(skb, qdisc, &qdisc->q);
|
qdisc->q.qlen++;
|
||||||
|
return __qdisc_requeue(skb, qdisc, prio2list(skb, qdisc));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fifo_fast_reset(struct Qdisc* qdisc)
|
static void pfifo_fast_reset(struct Qdisc* qdisc)
|
||||||
{
|
{
|
||||||
__qdisc_reset_queue(qdisc, &qdisc->q);
|
int prio;
|
||||||
|
struct sk_buff_head *list = qdisc_priv(qdisc);
|
||||||
|
|
||||||
|
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
|
||||||
|
__qdisc_reset_queue(qdisc, list + prio);
|
||||||
|
|
||||||
qdisc->qstats.backlog = 0;
|
qdisc->qstats.backlog = 0;
|
||||||
|
qdisc->q.qlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct Qdisc_ops fifo_fast_ops __read_mostly = {
|
static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb)
|
||||||
.id = "fifo_fast",
|
{
|
||||||
.priv_size = 0,
|
struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS };
|
||||||
.enqueue = fifo_fast_enqueue,
|
|
||||||
.dequeue = fifo_fast_dequeue,
|
memcpy(&opt.priomap, prio2band, TC_PRIO_MAX+1);
|
||||||
.requeue = fifo_fast_requeue,
|
NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
|
||||||
.reset = fifo_fast_reset,
|
return skb->len;
|
||||||
|
|
||||||
|
nla_put_failure:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
|
||||||
|
{
|
||||||
|
int prio;
|
||||||
|
struct sk_buff_head *list = qdisc_priv(qdisc);
|
||||||
|
|
||||||
|
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
|
||||||
|
skb_queue_head_init(list + prio);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct Qdisc_ops pfifo_fast_ops __read_mostly = {
|
||||||
|
.id = "pfifo_fast",
|
||||||
|
.priv_size = PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
|
||||||
|
.enqueue = pfifo_fast_enqueue,
|
||||||
|
.dequeue = pfifo_fast_dequeue,
|
||||||
|
.requeue = pfifo_fast_requeue,
|
||||||
|
.init = pfifo_fast_init,
|
||||||
|
.reset = pfifo_fast_reset,
|
||||||
|
.dump = pfifo_fast_dump,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -522,7 +577,7 @@ static void attach_one_default_qdisc(struct net_device *dev,
|
||||||
|
|
||||||
if (dev->tx_queue_len) {
|
if (dev->tx_queue_len) {
|
||||||
qdisc = qdisc_create_dflt(dev, dev_queue,
|
qdisc = qdisc_create_dflt(dev, dev_queue,
|
||||||
&fifo_fast_ops, TC_H_ROOT);
|
&pfifo_fast_ops, TC_H_ROOT);
|
||||||
if (!qdisc) {
|
if (!qdisc) {
|
||||||
printk(KERN_INFO "%s: activation failed\n", dev->name);
|
printk(KERN_INFO "%s: activation failed\n", dev->name);
|
||||||
return;
|
return;
|
||||||
|
@ -550,9 +605,9 @@ void dev_activate(struct net_device *dev)
|
||||||
int need_watchdog;
|
int need_watchdog;
|
||||||
|
|
||||||
/* No queueing discipline is attached to device;
|
/* No queueing discipline is attached to device;
|
||||||
* create default one i.e. fifo_fast for devices,
|
create default one i.e. pfifo_fast for devices,
|
||||||
* which need queueing and noqueue_qdisc for
|
which need queueing and noqueue_qdisc for
|
||||||
* virtual interfaces.
|
virtual interfaces
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (dev_all_qdisc_sleeping_noop(dev))
|
if (dev_all_qdisc_sleeping_noop(dev))
|
||||||
|
@ -576,7 +631,6 @@ static void dev_deactivate_queue(struct net_device *dev,
|
||||||
void *_qdisc_default)
|
void *_qdisc_default)
|
||||||
{
|
{
|
||||||
struct Qdisc *qdisc_default = _qdisc_default;
|
struct Qdisc *qdisc_default = _qdisc_default;
|
||||||
struct sk_buff *skb = NULL;
|
|
||||||
struct Qdisc *qdisc;
|
struct Qdisc *qdisc;
|
||||||
|
|
||||||
qdisc = dev_queue->qdisc;
|
qdisc = dev_queue->qdisc;
|
||||||
|
@ -588,8 +642,6 @@ static void dev_deactivate_queue(struct net_device *dev,
|
||||||
|
|
||||||
spin_unlock_bh(qdisc_lock(qdisc));
|
spin_unlock_bh(qdisc_lock(qdisc));
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree_skb(skb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool some_qdisc_is_running(struct net_device *dev, int lock)
|
static bool some_qdisc_is_running(struct net_device *dev, int lock)
|
||||||
|
|
Loading…
Reference in a new issue