summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/atm/ambassador.c4
-rw-r--r--drivers/atm/he.c2
-rw-r--r--drivers/atm/horizon.c2
-rw-r--r--drivers/atm/idt77252.c2
-rw-r--r--drivers/bluetooth/bluecard_cs.c8
-rw-r--r--drivers/bluetooth/bt3c_cs.c7
-rw-r--r--drivers/bluetooth/btuart_cs.c7
-rw-r--r--drivers/bluetooth/dtl1_cs.c7
-rw-r--r--drivers/bluetooth/hci_usb.c4
-rw-r--r--drivers/isdn/i4l/isdn_x25iface.c16
-rw-r--r--drivers/net/ethertap.c2
-rw-r--r--drivers/net/tg3.c35
-rw-r--r--drivers/net/wan/cycx_x25.c8
-rw-r--r--drivers/net/wan/dscc4.c1
-rw-r--r--drivers/net/wan/hdlc_x25.c14
-rw-r--r--drivers/net/wan/lapbether.c20
-rw-r--r--drivers/net/wan/x25_asy.c18
-rw-r--r--include/linux/netfilter_ipv4/ip_tables.h4
-rw-r--r--include/linux/tc_act/tc_ipt.h21
-rw-r--r--include/net/bluetooth/hci_core.h48
-rw-r--r--include/net/ip_vs.h2
-rw-r--r--include/net/pkt_cls.h186
-rw-r--r--include/net/tc_act/tc_ipt.h16
-rw-r--r--include/net/x25device.h17
-rw-r--r--net/8021q/vlan_dev.c23
-rw-r--r--net/Kconfig4
-rw-r--r--net/Makefile3
-rw-r--r--net/appletalk/ddp.c7
-rw-r--r--net/ax25/ax25_route.c16
-rw-r--r--net/bluetooth/af_bluetooth.c2
-rw-r--r--net/bluetooth/hci_core.c28
-rw-r--r--net/bluetooth/hci_event.c6
-rw-r--r--net/core/dev.c12
-rw-r--r--net/core/netfilter.c2
-rw-r--r--net/ipv4/Kconfig13
-rw-r--r--net/ipv4/Makefile3
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c2
-rw-r--r--net/ipv4/netfilter/ip_tables.c14
-rw-r--r--net/ipv4/netfilter/ipt_tcpmss.c12
-rw-r--r--net/ipv4/tcp.c4
-rw-r--r--net/ipv4/tcp_diag.c14
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv4/tcp_minisocks.c4
-rw-r--r--net/ipv4/xfrm4_input.c3
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/irda/qos.c11
-rw-r--r--net/sched/Kconfig9
-rw-r--r--net/sched/Makefile1
-rw-r--r--net/sched/cls_fw.c363
-rw-r--r--net/sched/cls_route.c49
-rw-r--r--net/sched/cls_rsvp.h48
-rw-r--r--net/sched/cls_tcindex.c38
-rw-r--r--net/sched/cls_u32.c152
-rw-r--r--net/sched/ipt.c392
-rw-r--r--net/sctp/outqueue.c10
-rw-r--r--net/x25/af_x25.c1
-rw-r--r--net/x25/x25_dev.c4
-rw-r--r--net/x25/x25_proc.c7
-rw-r--r--net/xfrm/Kconfig4
-rw-r--r--net/xfrm/xfrm_export.c1
60 files changed, 1073 insertions, 644 deletions
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 45b735af8c93..91fcd7955fe3 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -2261,7 +2261,7 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_
int err;
// read resources from PCI configuration space
- u8 irq = pci_dev->irq;
+ unsigned int irq = pci_dev->irq;
if (pci_dev->device == PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD) {
PRINTK (KERN_ERR, "skipped broken (PLX rev 2) card");
@@ -2439,6 +2439,8 @@ static struct pci_device_id amb_pci_tbl[] = {
{ 0, }
};
+MODULE_DEVICE_TABLE(pci, amb_pci_tbl);
+
static struct pci_driver amb_driver = {
.name = "amb",
.probe = amb_probe,
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 74b490bc49f7..6338181cf0dd 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -3051,6 +3051,8 @@ static struct pci_device_id he_pci_tbl[] = {
{ 0, }
};
+MODULE_DEVICE_TABLE(pci, he_pci_tbl);
+
static struct pci_driver he_driver = {
.name = "he",
.probe = he_init_one,
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index a3f3c2413f2f..7ae054473c23 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -2913,6 +2913,8 @@ static struct pci_device_id hrz_pci_tbl[] = {
{ 0, }
};
+MODULE_DEVICE_TABLE(pci, hrz_pci_tbl);
+
static struct pci_driver hrz_driver = {
.name = "horizon",
.probe = hrz_probe,
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index 6fc5b1de8b52..72ea27c15933 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -3820,6 +3820,8 @@ static struct pci_device_id idt77252_pci_tbl[] =
{ 0, }
};
+MODULE_DEVICE_TABLE(pci, idt77252_pci_tbl);
+
static struct pci_driver idt77252_driver = {
.name = "idt77252",
.id_table = idt77252_pci_tbl,
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 54ef5f941eb9..1d26a4db1360 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -34,6 +34,8 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
+#include <linux/moduleparam.h>
+
#include <linux/skbuff.h>
#include <asm/io.h>
@@ -54,11 +56,11 @@
/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0x86bc;
+static unsigned int irq_mask = 0x86bc;
static int irq_list[4] = { -1 };
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
+module_param(irq_mask, uint, 0);
+module_param_array(irq_list, int, NULL, 0);
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)");
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 305e030eb447..37bdb030e0fd 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -34,6 +34,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
+#include <linux/moduleparam.h>
#include <linux/skbuff.h>
#include <linux/string.h>
@@ -63,11 +64,11 @@
/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xffff;
+static unsigned int irq_mask = 0xffff;
static int irq_list[4] = { -1 };
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
+module_param(irq_mask, uint, 0);
+module_param_array(irq_list, int, NULL, 0);
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index f039c84e8218..7814bed545e2 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -33,6 +33,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
+#include <linux/moduleparam.h>
#include <linux/skbuff.h>
#include <linux/string.h>
@@ -59,11 +60,11 @@
/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xffff;
+static unsigned int irq_mask = 0xffff;
static int irq_list[4] = { -1 };
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
+module_param(irq_mask, uint, 0);
+module_param_array(irq_list, int, NULL, 0);
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth driver for Bluetooth PCMCIA cards with HCI UART interface");
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 91e0a2edf720..8579aebc7949 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -33,6 +33,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
+#include <linux/moduleparam.h>
#include <linux/skbuff.h>
#include <linux/string.h>
@@ -59,11 +60,11 @@
/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xffff;
+static unsigned int irq_mask = 0xffff;
static int irq_list[4] = { -1 };
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM(irq_list, "1-4i");
+module_param(irq_mask, uint, 0);
+module_param_array(irq_list, int, NULL, 0);
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth driver for Nokia Connectivity Card DTL-1");
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index d0c197db3ce4..3cbcc4155651 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -101,8 +101,12 @@ static struct usb_device_id blacklist_ids[] = {
{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
/* Broadcom BCM2035 */
+ { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_RESET | HCI_BROKEN_ISOC },
{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_BROKEN_ISOC },
+ /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
+ { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET | HCI_BROKEN_ISOC },
+
/* ISSC Bluetooth Adapter v3.1 */
{ USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c
index da1d2fb9fc8d..4ab7600cf9c1 100644
--- a/drivers/isdn/i4l/isdn_x25iface.c
+++ b/drivers/isdn/i4l/isdn_x25iface.c
@@ -21,6 +21,7 @@
#include <linux/netdevice.h>
#include <linux/concap.h>
#include <linux/wanrouter.h>
+#include <net/x25device.h>
#include "isdn_x25iface.h"
/* for debugging messages not to cause an oops when device pointer is NULL*/
@@ -191,12 +192,9 @@ int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb)
IX25DEBUG( "isdn_x25iface_receive %s \n", MY_DEVNAME(cprot->net_dev) );
if ( ( (ix25_pdata_t*) (cprot->proto_data) )
-> state == WAN_CONNECTED ){
- skb -> dev = cprot -> net_dev;
- skb -> protocol = htons(ETH_P_X25);
- skb -> pkt_type = PACKET_HOST;
if( skb_push(skb, 1)){
skb -> data[0]=0x00;
- skb -> mac.raw = skb -> data;
+ skb->protocol = x25_type_trans(skb, cprot->net_dev);
netif_rx(skb);
return 0;
}
@@ -224,10 +222,7 @@ int isdn_x25iface_connect_ind(struct concap_proto *cprot)
*state_p = WAN_CONNECTED;
if( skb ){
*( skb_put(skb, 1) ) = 0x01;
- skb -> mac.raw = skb -> data;
- skb -> dev = cprot -> net_dev;
- skb -> protocol = htons(ETH_P_X25);
- skb -> pkt_type = PACKET_HOST;
+ skb->protocol = x25_type_trans(skb, cprot->net_dev);
netif_rx(skb);
return 0;
} else {
@@ -256,10 +251,7 @@ int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
skb = dev_alloc_skb(1);
if( skb ){
*( skb_put(skb, 1) ) = 0x02;
- skb -> mac.raw = skb -> data;
- skb -> dev = cprot -> net_dev;
- skb -> protocol = htons(ETH_P_X25);
- skb -> pkt_type = PACKET_HOST;
+ skb->protocol = x25_type_trans(skb, cprot->net_dev);
netif_rx(skb);
return 0;
} else {
diff --git a/drivers/net/ethertap.c b/drivers/net/ethertap.c
index ef47c5c9aff8..24f237b22a75 100644
--- a/drivers/net/ethertap.c
+++ b/drivers/net/ethertap.c
@@ -124,7 +124,7 @@ static int ethertap_open(struct net_device *dev)
struct net_local *lp = netdev_priv(dev);
if (ethertap_debug > 2)
- printk(KERN_DEBUG "%s: Doing ethertap_open()...", dev->name);
+ printk(KERN_DEBUG "%s: Doing ethertap_open()...\n", dev->name);
lp->nl = netlink_kernel_create(dev->base_addr, ethertap_rx);
if (lp->nl == NULL)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 02cc93065231..6bd0f97a76d7 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -60,8 +60,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.11"
-#define DRV_MODULE_RELDATE "October 20, 2004"
+#define DRV_MODULE_VERSION "3.13"
+#define DRV_MODULE_RELDATE "November 1, 2004"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -418,6 +418,20 @@ static void tg3_enable_ints(struct tg3 *tp)
tg3_cond_int(tp);
}
+/* tg3_restart_ints
+ * similar to tg3_enable_ints, but it can return without flushing the
+ * PIO write which reenables interrupts
+ */
+static void tg3_restart_ints(struct tg3 *tp)
+{
+ tw32(TG3PCI_MISC_HOST_CTRL,
+ (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000);
+ mmiowb();
+
+ tg3_cond_int(tp);
+}
+
static inline void tg3_netif_stop(struct tg3 *tp)
{
netif_poll_disable(tp->dev);
@@ -2145,7 +2159,16 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED;
} else if (mac_status & (MAC_STATUS_PCS_SYNCED |
MAC_STATUS_SIGNAL_DET)) {
- sg_dig_status = tr32(SG_DIG_STATUS);
+ int i;
+
+ /* Giver time to negotiate (~200ms) */
+ for (i = 0; i < 40000; i++) {
+ sg_dig_status = tr32(SG_DIG_STATUS);
+ if (sg_dig_status & (0x3))
+ break;
+ udelay(5);
+ }
+ mac_status = tr32(MAC_STATUS);
if ((sg_dig_status & (1 << 1)) &&
(mac_status & MAC_STATUS_PCS_SYNCED)) {
@@ -2730,6 +2753,7 @@ next_pkt_nopost:
tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
sw_idx);
}
+ mmiowb();
return received;
}
@@ -2788,7 +2812,7 @@ static int tg3_poll(struct net_device *netdev, int *budget)
if (done) {
spin_lock_irqsave(&tp->lock, flags);
__netif_rx_complete(netdev);
- tg3_enable_ints(tp);
+ tg3_restart_ints(tp);
spin_unlock_irqrestore(&tp->lock, flags);
}
@@ -3177,6 +3201,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
out_unlock:
+ mmiowb();
spin_unlock_irqrestore(&tp->tx_lock, flags);
dev->trans_start = jiffies;
@@ -8224,7 +8249,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
spin_lock_init(&tp->indirect_lock);
INIT_WORK(&tp->reset_task, tg3_reset_task, tp);
- tp->regs = ioremap(tg3reg_base, tg3reg_len);
+ tp->regs = ioremap_nocache(tg3reg_base, tg3reg_len);
if (tp->regs == 0UL) {
printk(KERN_ERR PFX "Cannot map device registers, "
"aborting.\n");
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 9b26d3c0e9cc..5b48cd8568f5 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -92,6 +92,8 @@
#include <linux/cyclomx.h> /* Cyclom 2X common user API definitions */
#include <linux/cycx_x25.h> /* X.25 firmware API definitions */
+#include <net/x25device.h>
+
/* Defines & Macros */
#define CYCX_X25_MAX_CMD_RETRY 5
#define CYCX_X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */
@@ -1486,11 +1488,7 @@ static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
ptr = skb_put(skb, 1);
*ptr = event;
- skb->dev = dev;
- skb->protocol = htons(ETH_P_X25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
-
+ skb->protocol = x25_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies; /* timestamp */
}
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 982bb213e686..e998cfff9fa9 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -519,7 +519,6 @@ inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, struct net_device *dev)
dpriv->rx_skbuff[dirty] = skb;
if (skb) {
skb->protocol = hdlc_type_trans(skb, dev);
- skb->mac.raw = skb->data;
rx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data,
len, PCI_DMA_FROMDEVICE);
} else {
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index 5231063c9d64..07e5eef1fe0f 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -23,6 +23,8 @@
#include <linux/rtnetlink.h>
#include <linux/hdlc.h>
+#include <net/x25device.h>
+
/* These functions are callbacks called by LAPB layer */
static void x25_connect_disconnect(struct net_device *dev, int reason, int code)
@@ -38,11 +40,7 @@ static void x25_connect_disconnect(struct net_device *dev, int reason, int code)
ptr = skb_put(skb, 1);
*ptr = code;
- skb->dev = dev;
- skb->protocol = htons(ETH_P_X25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
-
+ skb->protocol = x25_type_trans(skb, dev);
netif_rx(skb);
}
@@ -74,11 +72,7 @@ static int x25_data_indication(struct net_device *dev, struct sk_buff *skb)
ptr = skb->data;
*ptr = 0;
- skb->dev = dev;
- skb->protocol = htons(ETH_P_X25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
-
+ skb->protocol = x25_type_trans(skb, dev);
return netif_rx(skb);
}
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index c8f3187e12c9..7f2e3653c5e5 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -43,6 +43,8 @@
#include <linux/lapb.h>
#include <linux/init.h>
+#include <net/x25device.h>
+
static char bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
/* If this number is made larger, check that the temporary string buffer
@@ -137,11 +139,7 @@ static int lapbeth_data_indication(struct net_device *dev, struct sk_buff *skb)
ptr = skb->data;
*ptr = 0x00;
- skb->dev = dev;
- skb->protocol = htons(ETH_P_X25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
-
+ skb->protocol = x25_type_trans(skb, dev);
skb->dev->last_rx = jiffies;
return netif_rx(skb);
}
@@ -233,11 +231,7 @@ static void lapbeth_connected(struct net_device *dev, int reason)
ptr = skb_put(skb, 1);
*ptr = 0x01;
- skb->dev = dev;
- skb->protocol = htons(ETH_P_X25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
-
+ skb->protocol = x25_type_trans(skb, dev);
skb->dev->last_rx = jiffies;
netif_rx(skb);
}
@@ -255,11 +249,7 @@ static void lapbeth_disconnected(struct net_device *dev, int reason)
ptr = skb_put(skb, 1);
*ptr = 0x02;
- skb->dev = dev;
- skb->protocol = htons(ETH_P_X25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
-
+ skb->protocol = x25_type_trans(skb, dev);
skb->dev->last_rx = jiffies;
netif_rx(skb);
}
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 57e9758eb83f..03f4331b4a22 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -34,6 +34,8 @@
#include <linux/init.h>
#include "x25_asy.h"
+#include <net/x25device.h>
+
static struct net_device **x25_asy_devs;
static int x25_asy_maxdev = SL_NRUNIT;
@@ -209,10 +211,8 @@ static void x25_asy_bump(struct x25_asy *sl)
return;
}
skb_push(skb,1); /* LAPB internal control */
- skb->dev = sl->dev;
memcpy(skb_put(skb,count), sl->rbuff, count);
- skb->mac.raw=skb->data;
- skb->protocol=htons(ETH_P_X25);
+ skb->protocol = x25_type_trans(skb, sl->dev);
if((err=lapb_data_received(skb->dev, skb))!=LAPB_OK)
{
kfree_skb(skb);
@@ -419,11 +419,7 @@ static void x25_asy_connected(struct net_device *dev, int reason)
ptr = skb_put(skb, 1);
*ptr = 0x01;
- skb->dev = sl->dev;
- skb->protocol = htons(ETH_P_X25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
-
+ skb->protocol = x25_type_trans(skb, sl->dev);
netif_rx(skb);
sl->dev->last_rx = jiffies;
}
@@ -442,11 +438,7 @@ static void x25_asy_disconnected(struct net_device *dev, int reason)
ptr = skb_put(skb, 1);
*ptr = 0x02;
- skb->dev = sl->dev;
- skb->protocol = htons(ETH_P_X25);
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_HOST;
-
+ skb->protocol = x25_type_trans(skb, sl->dev);
netif_rx(skb);
sl->dev->last_rx = jiffies;
}
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index defc7bc472d9..642fb5c614cb 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -413,6 +413,10 @@ extern void ipt_unregister_target(struct ipt_target *target);
extern int ipt_register_match(struct ipt_match *match);
extern void ipt_unregister_match(struct ipt_match *match);
+extern struct ipt_target *
+__ipt_find_target_lock(const char *name, int *error);
+extern void __ipt_mutex_up(void);
+
/* Furniture shopping... */
struct ipt_table
{
diff --git a/include/linux/tc_act/tc_ipt.h b/include/linux/tc_act/tc_ipt.h
new file mode 100644
index 000000000000..4b6f7b6c7a79
--- /dev/null
+++ b/include/linux/tc_act/tc_ipt.h
@@ -0,0 +1,21 @@
+#ifndef __LINUX_TC_IPT_H
+#define __LINUX_TC_IPT_H
+
+#include <linux/pkt_cls.h>
+
+#define TCA_ACT_IPT 6
+
+enum
+{
+ TCA_IPT_UNSPEC,
+ TCA_IPT_TABLE,
+ TCA_IPT_HOOK,
+ TCA_IPT_INDEX,
+ TCA_IPT_CNT,
+ TCA_IPT_TM,
+ TCA_IPT_TARG,
+ __TCA_IPT_MAX
+};
+#define TCA_IPT_MAX (__TCA_IPT_MAX - 1)
+
+#endif
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2c9995af03a8..ef0ecb6c75fd 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -161,7 +161,9 @@ struct hci_conn {
extern struct hci_proto *hci_proto[];
extern struct list_head hci_dev_list;
+extern struct list_head hci_cb_list;
extern rwlock_t hci_dev_list_lock;
+extern rwlock_t hci_cb_list_lock;
/* ----- Inquiry cache ----- */
#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
@@ -229,7 +231,7 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
struct hci_conn_hash *h = &hdev->conn_hash;
list_del(&c->list);
if (c->type == ACL_LINK)
- h->acl_num++;
+ h->acl_num--;
else
h->sco_num--;
}
@@ -491,6 +493,50 @@ static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status)
int hci_register_proto(struct hci_proto *hproto);
int hci_unregister_proto(struct hci_proto *hproto);
+
+/* ----- HCI callbacks ----- */
+struct hci_cb {
+ struct list_head list;
+
+ char *name;
+
+ void (*auth_cfm) (struct hci_conn *conn, __u8 status);
+ void (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
+};
+
+static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
+{
+ struct list_head *p;
+
+ hci_proto_auth_cfm(conn, status);
+
+ read_lock_bh(&hci_cb_list_lock);
+ list_for_each(p, &hci_cb_list) {
+ struct hci_cb *cb = list_entry(p, struct hci_cb, list);
+ if (cb->auth_cfm)
+ cb->auth_cfm(conn, status);
+ }
+ read_unlock_bh(&hci_cb_list_lock);
+}
+
+static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
+{
+ struct list_head *p;
+
+ hci_proto_encrypt_cfm(conn, status);
+
+ read_lock_bh(&hci_cb_list_lock);
+ list_for_each(p, &hci_cb_list) {
+ struct hci_cb *cb = list_entry(p, struct hci_cb, list);
+ if (cb->encrypt_cfm)
+ cb->encrypt_cfm(conn, status, encrypt);
+ }
+ read_unlock_bh(&hci_cb_list_lock);
+}
+
+int hci_register_cb(struct hci_cb *hcb);
+int hci_unregister_cb(struct hci_cb *hcb);
+
int hci_register_notifier(struct notifier_block *nb);
int hci_unregister_notifier(struct notifier_block *nb);
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 9ba24794afe3..4c441ef94d93 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -8,7 +8,7 @@
#include <asm/types.h> /* For __uXX types */
-#define IP_VS_VERSION_CODE 0x010200
+#define IP_VS_VERSION_CODE 0x010201
#define NVERSION(version) \
(version >> 16) & 0xFF, \
(version >> 8) & 0xFF, \
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 2eb89bbaec87..3dd20562a196 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -3,6 +3,7 @@
#include <linux/pkt_cls.h>
#include <net/sch_generic.h>
+#include <net/act_api.h>
/* Basic packet classifier frontend definitions. */
@@ -41,4 +42,189 @@ cls_set_class(struct tcf_proto *tp, unsigned long *clp,
return old_cl;
}
+static inline void
+tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base)
+{
+ unsigned long cl;
+
+ cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, r->classid);
+ cl = cls_set_class(tp, &r->class, cl);
+ if (cl)
+ tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+}
+
+static inline void
+tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
+{
+ unsigned long cl;
+
+ if ((cl = __cls_set_class(&r->class, 0)) != 0)
+ tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+}
+
+#ifdef CONFIG_NET_CLS_ACT
+static inline int
+tcf_change_act_police(struct tcf_proto *tp, struct tc_action **action,
+ struct rtattr *act_police_tlv, struct rtattr *rate_tlv)
+{
+ int ret;
+ struct tc_action *act;
+
+ act = kmalloc(sizeof(*act), GFP_KERNEL);
+ if (NULL == act)
+ return -ENOMEM;
+ memset(act, 0, sizeof(*act));
+
+ ret = tcf_action_init_1(act_police_tlv, rate_tlv, act, "police",
+ TCA_ACT_NOREPLACE, TCA_ACT_BIND);
+ if (ret < 0) {
+ tcf_action_destroy(act, TCA_ACT_UNBIND);
+ return ret;
+ }
+
+ act->type = TCA_OLD_COMPAT;
+
+ if (*action) {
+ tcf_tree_lock(tp);
+ act = xchg(action, act);
+ tcf_tree_unlock(tp);
+
+ tcf_action_destroy(act, TCA_ACT_UNBIND);
+ } else
+ *action = act;
+
+ return 0;
+}
+
+static inline int
+tcf_change_act(struct tcf_proto *tp, struct tc_action **action,
+ struct rtattr *act_tlv, struct rtattr *rate_tlv)
+{
+ int ret;
+ struct tc_action *act;
+
+ act = kmalloc(sizeof(*act), GFP_KERNEL);
+ if (NULL == act)
+ return -ENOMEM;
+ memset(act, 0, sizeof(*act));
+
+ ret = tcf_action_init(act_tlv, rate_tlv, act, NULL,
+ TCA_ACT_NOREPLACE, TCA_ACT_BIND);
+ if (ret < 0) {
+ tcf_action_destroy(act, TCA_ACT_UNBIND);
+ return ret;
+ }
+
+ if (*action) {
+ tcf_tree_lock(tp);
+ act = xchg(action, act);
+ tcf_tree_unlock(tp);
+
+ tcf_action_destroy(act, TCA_ACT_UNBIND);
+ } else
+ *action = act;
+
+ return 0;
+}
+
+static inline int
+tcf_dump_act(struct sk_buff *skb, struct tc_action *action,
+ int act_type, int compat_type)
+{
+ /*
+ * again for backward compatible mode - we want
+ * to work with both old and new modes of entering
+ * tc data even if iproute2 was newer - jhs
+ */
+ if (action) {
+ struct rtattr * p_rta = (struct rtattr*) skb->tail;
+
+ if (action->type != TCA_OLD_COMPAT) {
+ RTA_PUT(skb, act_type, 0, NULL);
+ if (tcf_action_dump(skb, action, 0, 0) < 0)
+ goto rtattr_failure;
+ } else {
+ RTA_PUT(skb, compat_type, 0, NULL);
+ if (tcf_action_dump_old(skb, action, 0, 0) < 0)
+ goto rtattr_failure;
+ }
+
+ p_rta->rta_len = skb->tail - (u8*)p_rta;
+ }
+ return 0;
+
+rtattr_failure:
+ return -1;
+}
+#endif /* CONFIG_NET_CLS_ACT */
+
+#ifdef CONFIG_NET_CLS_IND
+static inline int
+tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv)
+{
+ if (RTA_PAYLOAD(indev_tlv) >= IFNAMSIZ) {
+ printk("cls: bad indev name %s\n", (char *) RTA_DATA(indev_tlv));
+ return -EINVAL;
+ }
+
+ memset(indev, 0, IFNAMSIZ);
+ sprintf(indev, "%s", (char *) RTA_DATA(indev_tlv));
+
+ return 0;
+}
+
+static inline int
+tcf_match_indev(struct sk_buff *skb, char *indev)
+{
+ if (0 != indev[0]) {
+ if (NULL == skb->input_dev)
+ return 0;
+ else if (0 != strcmp(indev, skb->input_dev->name))
+ return 0;
+ }
+
+ return 1;
+}
+#endif /* CONFIG_NET_CLS_IND */
+
+#ifdef CONFIG_NET_CLS_POLICE
+static inline int
+tcf_change_police(struct tcf_proto *tp, struct tcf_police **police,
+ struct rtattr *police_tlv, struct rtattr *rate_tlv)
+{
+ struct tcf_police *p = tcf_police_locate(police_tlv, rate_tlv);
+
+ if (*police) {
+ tcf_tree_lock(tp);
+ p = xchg(police, p);
+ tcf_tree_unlock(tp);
+
+ tcf_police_release(p, TCA_ACT_UNBIND);
+ } else
+ *police = p;
+
+ return 0;
+}
+
+static inline int
+tcf_dump_police(struct sk_buff *skb, struct tcf_police *police,
+ int police_type)
+{
+ if (police) {
+ struct rtattr * p_rta = (struct rtattr*) skb->tail;
+
+ RTA_PUT(skb, police_type, 0, NULL);
+
+ if (tcf_police_dump(skb, police) < 0)
+ goto rtattr_failure;
+
+ p_rta->rta_len = skb->tail - (u8*)p_rta;
+ }
+ return 0;
+
+rtattr_failure:
+ return -1;
+}
+#endif /* CONFIG_NET_CLS_POLICE */
+
#endif
diff --git a/include/net/tc_act/tc_ipt.h b/include/net/tc_act/tc_ipt.h
new file mode 100644
index 000000000000..02eccebd55ae
--- /dev/null
+++ b/include/net/tc_act/tc_ipt.h
@@ -0,0 +1,16 @@
+#ifndef __NET_TC_IPT_H
+#define __NET_TC_IPT_H
+
+#include <net/act_api.h>
+
+struct ipt_entry_target;
+
+struct tcf_ipt
+{
+ tca_gen(ipt);
+ u32 hook;
+ char *tname;
+ struct ipt_entry_target *t;
+};
+
+#endif
diff --git a/include/net/x25device.h b/include/net/x25device.h
new file mode 100644
index 000000000000..cf36a20ea3c5
--- /dev/null
+++ b/include/net/x25device.h
@@ -0,0 +1,17 @@
+#ifndef _X25DEVICE_H
+#define _X25DEVICE_H
+
+#include <linux/if_ether.h>
+#include <linux/if_packet.h>
+#include <linux/skbuff.h>
+
+static inline unsigned short x25_type_trans(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ skb->mac.raw = skb->data;
+ skb->input_dev = skb->dev = dev;
+ skb->pkt_type = PACKET_HOST;
+
+ return htons(ETH_P_X25);
+}
+#endif
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index ead778b5dceb..942bde0f7479 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -484,26 +484,13 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
veth->h_vlan_proto, veth->h_vlan_TCI, veth->h_vlan_encapsulated_proto);
#endif
- skb->dev = VLAN_DEV_INFO(dev)->real_dev;
-
- {
- /* Please note, dev_queue_xmit consumes the pkt regardless of the
- * error value. So, will copy the skb first and free if successful.
- */
- struct sk_buff* skb2 = skb_get(skb);
- int rv = dev_queue_xmit(skb2);
- if (rv == 0) {
- /* Was success, need to free the skb reference since we bumped up the
- * user count above.
- */
+ stats->tx_packets++; /* for statics only */
+ stats->tx_bytes += skb->len;
- stats->tx_packets++; /* for statics only */
- stats->tx_bytes += skb->len;
+ skb->dev = VLAN_DEV_INFO(dev)->real_dev;
+ dev_queue_xmit(skb);
- kfree_skb(skb);
- }
- return rv;
- }
+ return 0;
}
int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
diff --git a/net/Kconfig b/net/Kconfig
index d682d05cbf3f..155754c8e144 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -219,6 +219,10 @@ source "net/bridge/netfilter/Kconfig"
endif
+config XFRM
+ bool
+ depends on NET
+
source "net/xfrm/Kconfig"
source "net/sctp/Kconfig"
diff --git a/net/Makefile b/net/Makefile
index a46436e0fcc2..8e2bdc025ab8 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -15,7 +15,8 @@ obj-$(CONFIG_NET) += $(tmp-y)
# LLC has to be linked before the files in net/802/
obj-$(CONFIG_LLC) += llc/
obj-$(CONFIG_NET) += ethernet/ 802/ sched/ netlink/
-obj-$(CONFIG_INET) += ipv4/ xfrm/
+obj-$(CONFIG_INET) += ipv4/
+obj-$(CONFIG_XFRM) += xfrm/
obj-$(CONFIG_UNIX) += unix/
ifneq ($(CONFIG_IPV6),)
obj-y += ipv6/
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 588cbe1ec16f..8eada1ca17d8 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -78,13 +78,6 @@ static inline void __atalk_insert_socket(struct sock *sk)
sk_add_node(sk, &atalk_sockets);
}
-static inline void atalk_insert_socket(struct sock *sk)
-{
- write_lock_bh(&atalk_sockets_lock);
- __atalk_insert_socket(sk);
- write_unlock_bh(&atalk_sockets_lock);
-}
-
static inline void atalk_remove_socket(struct sock *sk)
{
write_lock_bh(&atalk_sockets_lock);
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 82c3c451fbd9..1090ac6dc058 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -41,22 +41,6 @@ static rwlock_t ax25_route_lock = RW_LOCK_UNLOCKED;
static ax25_route *ax25_get_route(ax25_address *, struct net_device *);
-/*
- * small macro to drop non-digipeated digipeaters and reverse path
- */
-static inline void ax25_route_invert(ax25_digi *in, ax25_digi *out)
-{
- int k;
-
- for (k = 0; k < in->ndigi; k++)
- if (!in->repeated[k])
- break;
-
- in->ndigi = k;
-
- ax25_digi_invert(in, out);
-}
-
void ax25_rt_device_down(struct net_device *dev)
{
ax25_route *s, *t, *ax25_rt;
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 53e90098c20c..8ff58bc2bf27 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -51,7 +51,7 @@
#define BT_DBG(D...)
#endif
-#define VERSION "2.6"
+#define VERSION "2.7"
struct proc_dir_entry *proc_bt;
EXPORT_SYMBOL(proc_bt);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e7d26b0f9afa..830a7a73bb2b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -65,6 +65,10 @@ rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
LIST_HEAD(hci_dev_list);
rwlock_t hci_dev_list_lock = RW_LOCK_UNLOCKED;
+/* HCI callback list */
+LIST_HEAD(hci_cb_list);
+rwlock_t hci_cb_list_lock = RW_LOCK_UNLOCKED;
+
/* HCI protocols */
#define HCI_MAX_PROTO 2
struct hci_proto *hci_proto[HCI_MAX_PROTO];
@@ -930,6 +934,30 @@ int hci_unregister_proto(struct hci_proto *hp)
}
EXPORT_SYMBOL(hci_unregister_proto);
+int hci_register_cb(struct hci_cb *cb)
+{
+ BT_DBG("%p name %s", cb, cb->name);
+
+ write_lock_bh(&hci_cb_list_lock);
+ list_add(&cb->list, &hci_cb_list);
+ write_unlock_bh(&hci_cb_list_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(hci_register_cb);
+
+int hci_unregister_cb(struct hci_cb *cb)
+{
+ BT_DBG("%p name %s", cb, cb->name);
+
+ write_lock_bh(&hci_cb_list_lock);
+ list_del(&cb->list);
+ write_unlock_bh(&hci_cb_list_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(hci_unregister_cb);
+
static int hci_send_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 22b435cd7d62..93f34e3ede10 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -739,7 +739,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
conn->link_mode |= HCI_LM_AUTH;
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
- hci_proto_auth_cfm(conn, ev->status);
+ hci_auth_cfm(conn, ev->status);
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
if (!ev->status) {
@@ -751,7 +751,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
sizeof(cp), &cp);
} else {
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
- hci_proto_encrypt_cfm(conn, ev->status);
+ hci_encrypt_cfm(conn, ev->status, 0x00);
}
}
}
@@ -780,7 +780,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
}
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
- hci_proto_encrypt_cfm(conn, ev->status);
+ hci_encrypt_cfm(conn, ev->status, ev->encrypt);
}
hci_dev_unlock(hdev);
diff --git a/net/core/dev.c b/net/core/dev.c
index a9e9c01258e2..b62614574c7c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1261,6 +1261,11 @@ int dev_queue_xmit(struct sk_buff *skb)
struct Qdisc *q;
int rc = -ENOMEM;
+ /* Disable soft irqs for various locks below. Also
+ * stops preemption for RCU.
+ */
+ local_bh_disable();
+
if (skb_shinfo(skb)->frag_list &&
!(dev->features & NETIF_F_FRAGLIST) &&
__skb_linearize(skb, GFP_ATOMIC))
@@ -1285,12 +1290,6 @@ int dev_queue_xmit(struct sk_buff *skb)
if (skb_checksum_help(skb, 0))
goto out_kfree_skb;
-
- /* Disable soft irqs for various locks below. Also
- * stops preemption for RCU.
- */
- local_bh_disable();
-
/* Updates of qdisc are serialized by queue_lock.
* The struct Qdisc which is pointed to by qdisc is now a
* rcu structure - it may be accessed without acquiring
@@ -3242,7 +3241,6 @@ EXPORT_SYMBOL(__dev_get_by_index);
EXPORT_SYMBOL(__dev_get_by_name);
EXPORT_SYMBOL(__dev_remove_pack);
EXPORT_SYMBOL(__skb_linearize);
-EXPORT_SYMBOL(call_netdevice_notifiers);
EXPORT_SYMBOL(dev_add_pack);
EXPORT_SYMBOL(dev_alloc_name);
EXPORT_SYMBOL(dev_close);
diff --git a/net/core/netfilter.c b/net/core/netfilter.c
index 9db8b4467f9d..b7f017877f7b 100644
--- a/net/core/netfilter.c
+++ b/net/core/netfilter.c
@@ -673,6 +673,7 @@ int ip_route_me_harder(struct sk_buff **pskb)
return 0;
}
+EXPORT_SYMBOL(ip_route_me_harder);
int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len)
{
@@ -818,7 +819,6 @@ void __init netfilter_init(void)
}
EXPORT_SYMBOL(ip_ct_attach);
-EXPORT_SYMBOL(ip_route_me_harder);
EXPORT_SYMBOL(nf_getsockopt);
EXPORT_SYMBOL(nf_hook_slow);
EXPORT_SYMBOL(nf_hooks);
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 270ceb7e104e..d62bb4cf6ba9 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -301,6 +301,7 @@ config SYN_COOKIES
config INET_AH
tristate "IP: AH transformation"
+ depends on INET
select XFRM
select CRYPTO
select CRYPTO_HMAC
@@ -313,6 +314,7 @@ config INET_AH
config INET_ESP
tristate "IP: ESP transformation"
+ depends on INET
select XFRM
select CRYPTO
select CRYPTO_HMAC
@@ -326,6 +328,7 @@ config INET_ESP
config INET_IPCOMP
tristate "IP: IPComp transformation"
+ depends on INET
select XFRM
select INET_TUNNEL
select CRYPTO
@@ -338,6 +341,7 @@ config INET_IPCOMP
config INET_TUNNEL
tristate "IP: tunnel transformation"
+ depends on INET
select XFRM
---help---
Support for generic IP tunnel transformation, which is required by
@@ -345,5 +349,14 @@ config INET_TUNNEL
If unsure, say Y.
+config IP_TCPDIAG
+ tristate "IP: TCP socket monitoring interface"
+ default y
+ ---help---
+ Support for TCP socket monitoring interface used by native Linux
+ tools such as ss.
+
+ If unsure, say Y.
+
source "net/ipv4/ipvs/Kconfig"
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 38f75099674f..e0f24f50ed3e 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -6,7 +6,7 @@ obj-y := utils.o route.o inetpeer.o protocol.o \
ip_input.o ip_fragment.o ip_forward.o ip_options.o \
ip_output.o ip_sockglue.o \
tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o tcp_minisocks.o \
- tcp_diag.o datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \
+ datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \
sysctl_net_ipv4.o fib_frontend.o fib_semantics.o fib_hash.o
obj-$(CONFIG_PROC_FS) += proc.o
@@ -22,6 +22,7 @@ obj-$(CONFIG_INET_TUNNEL) += xfrm4_tunnel.o
obj-$(CONFIG_IP_PNP) += ipconfig.o
obj-$(CONFIG_NETFILTER) += netfilter/
obj-$(CONFIG_IP_VS) += ipvs/
+obj-$(CONFIG_IP_TCPDIAG) += tcp_diag.o
obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
xfrm4_output.o
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index b3a6e6427c00..d14a4e342de3 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -312,6 +312,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
}
kmem_cache_free(ip_conntrack_expect_cachep, ct->master);
}
+ CONNTRACK_STAT_INC(delete);
WRITE_UNLOCK(&ip_conntrack_lock);
if (master)
@@ -320,7 +321,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
kmem_cache_free(ip_conntrack_cachep, ct);
atomic_dec(&ip_conntrack_count);
- CONNTRACK_STAT_INC(delete);
}
static void death_by_timeout(unsigned long ul_conntrack)
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 3e601a80d580..e470729ab5e3 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -477,6 +477,18 @@ ipt_find_target_lock(const char *name, int *error, struct semaphore *mutex)
return find_inlist_lock(&ipt_target, name, "ipt_", error, mutex);
}
+struct ipt_target *
+__ipt_find_target_lock(const char *name, int *error)
+{
+ return ipt_find_target_lock(name,error,&ipt_mutex);
+}
+
+void
+__ipt_mutex_up(void)
+{
+ up(&ipt_mutex);
+}
+
/* All zeroes == unconditional rule. */
static inline int
unconditional(const struct ipt_ip *ip)
@@ -1877,6 +1889,8 @@ EXPORT_SYMBOL(ipt_unregister_match);
EXPORT_SYMBOL(ipt_do_table);
EXPORT_SYMBOL(ipt_register_target);
EXPORT_SYMBOL(ipt_unregister_target);
+EXPORT_SYMBOL_GPL(__ipt_find_target_lock);
+EXPORT_SYMBOL_GPL(__ipt_mutex_up);
module_init(init);
module_exit(fini);
diff --git a/net/ipv4/netfilter/ipt_tcpmss.c b/net/ipv4/netfilter/ipt_tcpmss.c
index 5cda547e011e..4dc9b16ab4a3 100644
--- a/net/ipv4/netfilter/ipt_tcpmss.c
+++ b/net/ipv4/netfilter/ipt_tcpmss.c
@@ -87,18 +87,6 @@ match(const struct sk_buff *skb,
info->invert, hotdrop);
}
-static inline int find_syn_match(const struct ipt_entry_match *m)
-{
- const struct ipt_tcp *tcpinfo = (const struct ipt_tcp *)m->data;
-
- if (strcmp(m->u.kernel.match->name, "tcp") == 0
- && (tcpinfo->flg_cmp & TH_SYN)
- && !(tcpinfo->invflags & IPT_TCP_INV_FLAGS))
- return 1;
-
- return 0;
-}
-
static int
checkentry(const char *tablename,
const struct ipt_ip *ip,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 928ba3b541ed..0f59b48ed4cb 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2152,6 +2152,8 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
info->tcpi_total_retrans = tp->total_retrans;
}
+EXPORT_SYMBOL_GPL(tcp_get_info);
+
int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
int __user *optlen)
{
@@ -2358,8 +2360,6 @@ void __init tcp_init(void)
printk(KERN_INFO "TCP: Hash tables configured "
"(established %d bind %d)\n",
tcp_ehash_size << 1, tcp_bhash_size);
-
- tcpdiag_init();
}
EXPORT_SYMBOL(tcp_accept);
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 5c2bf6a08fcd..6c719559baab 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -776,9 +776,19 @@ static void tcpdiag_rcv(struct sock *sk, int len)
}
}
-void __init tcpdiag_init(void)
+static int __init tcpdiag_init(void)
{
tcpnl = netlink_kernel_create(NETLINK_TCPDIAG, tcpdiag_rcv);
if (tcpnl == NULL)
- panic("tcpdiag_init: Cannot create netlink socket.");
+ return -ENOMEM;
+ return 0;
}
+
+static void __exit tcpdiag_exit(void)
+{
+ sock_release(tcpnl->sk_socket);
+}
+
+module_init(tcpdiag_init);
+module_exit(tcpdiag_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 3df3ada30e6c..9efcbbd11566 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -535,6 +535,8 @@ inline struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr,
return sk;
}
+EXPORT_SYMBOL_GPL(tcp_v4_lookup);
+
static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
{
return secure_tcp_sequence_number(skb->nh.iph->daddr,
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 2bdc1975c319..2076d201f492 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -1075,7 +1075,3 @@ EXPORT_SYMBOL(tcp_child_process);
EXPORT_SYMBOL(tcp_create_openreq_child);
EXPORT_SYMBOL(tcp_timewait_state_process);
EXPORT_SYMBOL(tcp_tw_deschedule);
-
-#ifdef CONFIG_SYSCTL
-EXPORT_SYMBOL(sysctl_tcp_tw_recycle);
-#endif
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 47e54d4218df..2d3849c38a0f 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -9,6 +9,7 @@
*
*/
+#include <linux/module.h>
#include <linux/string.h>
#include <net/inet_ecn.h>
#include <net/ip.h>
@@ -19,6 +20,8 @@ int xfrm4_rcv(struct sk_buff *skb)
return xfrm4_rcv_encap(skb, 0);
}
+EXPORT_SYMBOL(xfrm4_rcv);
+
static inline void ipip_ecn_decapsulate(struct sk_buff *skb)
{
struct iphdr *outer_iph = skb->nh.iph;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 7112e8406a28..d6cadb2ceede 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -364,6 +364,8 @@ inline struct sock *tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
return sk;
}
+EXPORT_SYMBOL_GPL(tcp_v6_lookup);
+
/*
* Open request hash tables.
diff --git a/net/irda/qos.c b/net/irda/qos.c
index b02d2db0350c..d37dd2548325 100644
--- a/net/irda/qos.c
+++ b/net/irda/qos.c
@@ -211,17 +211,6 @@ static int msb_index (__u16 word)
return index;
}
-static inline __u32 byte_value(__u8 byte, __u32 *array)
-{
- int index;
-
- ASSERT(array != NULL, return -1;);
-
- index = msb_index(byte);
-
- return index_value(index, array);
-}
-
/*
* Function value_lower_bits (value, array)
*
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index e9306fb27983..2fe4fd4e34cf 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -393,7 +393,7 @@ config NET_ACT_GACT
---help---
You must have new iproute2 to use this feature.
This adds simple filtering actions like drop, accept etc.
-
+
config GACT_PROB
bool "generic Actions probability"
depends on NET_ACT_GACT
@@ -407,6 +407,13 @@ config NET_ACT_MIRRED
requires new iproute2
This allows packets to be mirrored or redirected to netdevices
+config NET_ACT_IPT
+ tristate "iptables Actions"
+ depends on NET_CLS_ACT && NETFILTER && IP_NF_IPTABLES
+ ---help---
+ requires new iproute2
+ This allows iptables targets to be used by tc filters
+
config NET_ACT_PEDIT
tristate "Generic Packet Editor Actions"
depends on NET_CLS_ACT
diff --git a/net/sched/Makefile b/net/sched/Makefile
index f69bb707f4a0..fad3a43a8939 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_NET_ACT_POLICE) += police.o
obj-$(CONFIG_NET_CLS_POLICE) += police.o
obj-$(CONFIG_NET_ACT_GACT) += gact.o
obj-$(CONFIG_NET_ACT_MIRRED) += mirred.o
+obj-$(CONFIG_NET_ACT_IPT) += ipt.o
obj-$(CONFIG_NET_ACT_PEDIT) += pedit.o
obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 7bb75eb1ee32..faaad5ceced3 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -56,16 +56,16 @@ struct fw_filter
struct fw_filter *next;
u32 id;
struct tcf_result res;
-#ifdef CONFIG_NET_CLS_ACT
- struct tc_action *action;
#ifdef CONFIG_NET_CLS_IND
- char indev[IFNAMSIZ];
-#endif
-#else
+ char indev[IFNAMSIZ];
+#endif /* CONFIG_NET_CLS_IND */
+#ifdef CONFIG_NET_CLS_ACT
+ struct tc_action *action;
+#else /* CONFIG_NET_CLS_ACT */
#ifdef CONFIG_NET_CLS_POLICE
struct tcf_police *police;
-#endif
-#endif
+#endif /* CONFIG_NET_CLS_POLICE */
+#endif /* CONFIG_NET_CLS_ACT */
};
static __inline__ int fw_hash(u32 handle)
@@ -84,47 +84,39 @@ static int fw_classify(struct sk_buff *skb, struct tcf_proto *tp,
u32 id = 0;
#endif
- if (head == NULL)
- goto old_method;
-
- for (f=head->ht[fw_hash(id)]; f; f=f->next) {
- if (f->id == id) {
- *res = f->res;
-#ifdef CONFIG_NET_CLS_ACT
+ if (head != NULL) {
+ for (f=head->ht[fw_hash(id)]; f; f=f->next) {
+ if (f->id == id) {
+ *res = f->res;
#ifdef CONFIG_NET_CLS_IND
- if (0 != f->indev[0]) {
- if (NULL == skb->input_dev) {
+ if (!tcf_match_indev(skb, f->indev))
+ continue;
+#endif /* CONFIG_NET_CLS_IND */
+#ifdef CONFIG_NET_CLS_ACT
+ if (f->action) {
+ int act_res = tcf_action_exec(skb, f->action, res);
+ if (act_res >= 0)
+ return act_res;
continue;
- } else {
- if (0 != strcmp(f->indev, skb->input_dev->name)) {
- continue;
- }
}
- }
-#endif
- if (f->action) {
- int pol_res = tcf_action_exec(skb, f->action, res);
- if (pol_res >= 0)
- return pol_res;
- } else
-#else
+#else /* CONFIG_NET_CLS_ACT */
#ifdef CONFIG_NET_CLS_POLICE
- if (f->police)
- return tcf_police(skb, f->police);
-#endif
-#endif
+ if (f->police)
+ return tcf_police(skb, f->police);
+#endif /* CONFIG_NET_CLS_POLICE */
+#endif /* CONFIG_NET_CLS_ACT */
+ return 0;
+ }
+ }
+ } else {
+ /* old method */
+ if (id && (TC_H_MAJ(id) == 0 || !(TC_H_MAJ(id^tp->q->handle)))) {
+ res->classid = id;
+ res->class = 0;
return 0;
}
}
- return -1;
-old_method:
- if (id && (TC_H_MAJ(id) == 0 ||
- !(TC_H_MAJ(id^tp->q->handle)))) {
- res->classid = id;
- res->class = 0;
- return 0;
- }
return -1;
}
@@ -163,20 +155,17 @@ static void fw_destroy(struct tcf_proto *tp)
for (h=0; h<256; h++) {
while ((f=head->ht[h]) != NULL) {
- unsigned long cl;
head->ht[h] = f->next;
-
- if ((cl = __cls_set_class(&f->res.class, 0)) != 0)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+ tcf_unbind_filter(tp, &f->res);
#ifdef CONFIG_NET_CLS_ACT
- if (f->action) {
- tcf_action_destroy(f->action,TCA_ACT_UNBIND);
- }
-#else
+ if (f->action)
+ tcf_action_destroy(f->action, TCA_ACT_UNBIND);
+#else /* CONFIG_NET_CLS_ACT */
#ifdef CONFIG_NET_CLS_POLICE
- tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif
-#endif
+ if (f->police)
+ tcf_police_release(f->police, TCA_ACT_UNBIND);
+#endif /* CONFIG_NET_CLS_POLICE */
+#endif /* CONFIG_NET_CLS_ACT */
kfree(f);
}
@@ -195,23 +184,18 @@ static int fw_delete(struct tcf_proto *tp, unsigned long arg)
for (fp=&head->ht[fw_hash(f->id)]; *fp; fp = &(*fp)->next) {
if (*fp == f) {
- unsigned long cl;
-
tcf_tree_lock(tp);
*fp = f->next;
tcf_tree_unlock(tp);
-
- if ((cl = cls_set_class(tp, &f->res.class, 0)) != 0)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+ tcf_unbind_filter(tp, &f->res);
#ifdef CONFIG_NET_CLS_ACT
- if (f->action) {
- tcf_action_destroy(f->action,TCA_ACT_UNBIND);
- }
-#else
+ if (f->action)
+ tcf_action_destroy(f->action,TCA_ACT_UNBIND);
+#else /* CONFIG_NET_CLS_ACT */
#ifdef CONFIG_NET_CLS_POLICE
tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif
-#endif
+#endif /* CONFIG_NET_CLS_POLICE */
+#endif /* CONFIG_NET_CLS_ACT */
kfree(f);
return 0;
}
@@ -220,21 +204,67 @@ out:
return -EINVAL;
}
+static int
+fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f,
+ struct rtattr **tb, struct rtattr **tca, unsigned long base)
+{
+ int err = -EINVAL;
+
+ if (tb[TCA_FW_CLASSID-1]) {
+ if (RTA_PAYLOAD(tb[TCA_FW_CLASSID-1]) != sizeof(u32))
+ goto errout;
+ f->res.classid = *(u32*)RTA_DATA(tb[TCA_FW_CLASSID-1]);
+ tcf_bind_filter(tp, &f->res, base);
+ }
+
+#ifdef CONFIG_NET_CLS_IND
+ if (tb[TCA_FW_INDEV-1]) {
+ err = tcf_change_indev(tp, f->indev, tb[TCA_FW_INDEV-1]);
+ if (err < 0)
+ goto errout;
+ }
+#endif /* CONFIG_NET_CLS_IND */
+
+#ifdef CONFIG_NET_CLS_ACT
+ if (tb[TCA_FW_POLICE-1]) {
+ err = tcf_change_act_police(tp, &f->action, tb[TCA_FW_POLICE-1],
+ tca[TCA_RATE-1]);
+ if (err < 0)
+ goto errout;
+ }
+
+ if (tb[TCA_FW_ACT-1]) {
+ err = tcf_change_act(tp, &f->action, tb[TCA_FW_ACT-1],
+ tca[TCA_RATE-1]);
+ if (err < 0)
+ goto errout;
+ }
+#else /* CONFIG_NET_CLS_ACT */
+#ifdef CONFIG_NET_CLS_POLICE
+ if (tb[TCA_FW_POLICE-1]) {
+ err = tcf_change_police(tp, &f->police, tb[TCA_FW_POLICE-1],
+ tca[TCA_RATE-1]);
+ if (err < 0)
+ goto errout;
+ }
+#endif /* CONFIG_NET_CLS_POLICE */
+#endif /* CONFIG_NET_CLS_ACT */
+
+ err = 0;
+errout:
+ return err;
+}
+
static int fw_change(struct tcf_proto *tp, unsigned long base,
u32 handle,
struct rtattr **tca,
unsigned long *arg)
{
struct fw_head *head = (struct fw_head*)tp->root;
- struct fw_filter *f;
+ struct fw_filter *f = (struct fw_filter *) *arg;
struct rtattr *opt = tca[TCA_OPTIONS-1];
struct rtattr *tb[TCA_FW_MAX];
int err;
-#ifdef CONFIG_NET_CLS_ACT
- struct tc_action *act = NULL;
- int ret;
-#endif
-
if (!opt)
return handle ? -EINVAL : 0;
@@ -242,85 +272,10 @@ static int fw_change(struct tcf_proto *tp, unsigned long base,
if (rtattr_parse(tb, TCA_FW_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
return -EINVAL;
- if ((f = (struct fw_filter*)*arg) != NULL) {
- /* Node exists: adjust only classid */
-
+ if (f != NULL) {
if (f->id != handle && handle)
return -EINVAL;
- if (tb[TCA_FW_CLASSID-1]) {
- unsigned long cl;
-
- f->res.classid = *(u32*)RTA_DATA(tb[TCA_FW_CLASSID-1]);
- cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid);
- cl = cls_set_class(tp, &f->res.class, cl);
- if (cl)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
- }
-#ifdef CONFIG_NET_CLS_ACT
- if (tb[TCA_FW_POLICE-1]) {
- act = kmalloc(sizeof(*act),GFP_KERNEL);
- if (NULL == act)
- return -ENOMEM;
-
- memset(act,0,sizeof(*act));
- ret = tcf_action_init_1(tb[TCA_FW_POLICE-1], tca[TCA_RATE-1] ,act,"police",TCA_ACT_NOREPLACE,TCA_ACT_BIND);
- if (0 > ret){
- tcf_action_destroy(act,TCA_ACT_UNBIND);
- return ret;
- }
- act->type = TCA_OLD_COMPAT;
-
- sch_tree_lock(tp->q);
- act = xchg(&f->action, act);
- sch_tree_unlock(tp->q);
-
- tcf_action_destroy(act,TCA_ACT_UNBIND);
-
- }
-
- if(tb[TCA_FW_ACT-1]) {
- act = kmalloc(sizeof(*act),GFP_KERNEL);
- if (NULL == act)
- return -ENOMEM;
- memset(act,0,sizeof(*act));
- ret = tcf_action_init(tb[TCA_FW_ACT-1], tca[TCA_RATE-1],act,NULL, TCA_ACT_NOREPLACE,TCA_ACT_BIND);
- if (0 > ret) {
- tcf_action_destroy(act,TCA_ACT_UNBIND);
- return ret;
- }
-
- sch_tree_lock(tp->q);
- act = xchg(&f->action, act);
- sch_tree_unlock(tp->q);
-
- tcf_action_destroy(act,TCA_ACT_UNBIND);
- }
-#ifdef CONFIG_NET_CLS_IND
- if(tb[TCA_FW_INDEV-1]) {
- struct rtattr *idev = tb[TCA_FW_INDEV-1];
- if (RTA_PAYLOAD(idev) >= IFNAMSIZ) {
- printk("cls_fw: bad indev name %s\n",(char*)RTA_DATA(idev));
- err = -EINVAL;
- goto errout;
- }
- memset(f->indev,0,IFNAMSIZ);
- sprintf(f->indev, "%s", (char*)RTA_DATA(idev));
- }
-#endif
-#else /* only POLICE defined */
-#ifdef CONFIG_NET_CLS_POLICE
- if (tb[TCA_FW_POLICE-1]) {
- struct tcf_police *police = tcf_police_locate(tb[TCA_FW_POLICE-1], tca[TCA_RATE-1]);
-
- tcf_tree_lock(tp);
- police = xchg(&f->police, police);
- tcf_tree_unlock(tp);
-
- tcf_police_release(police,TCA_ACT_UNBIND);
- }
-#endif
-#endif
- return 0;
+ return fw_change_attrs(tp, f, tb, tca, base);
}
if (!handle)
@@ -344,45 +299,9 @@ static int fw_change(struct tcf_proto *tp, unsigned long base,
f->id = handle;
- if (tb[TCA_FW_CLASSID-1]) {
- err = -EINVAL;
- if (RTA_PAYLOAD(tb[TCA_FW_CLASSID-1]) != 4)
- goto errout;
- f->res.classid = *(u32*)RTA_DATA(tb[TCA_FW_CLASSID-1]);
- cls_set_class(tp, &f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid));
- }
-
-#ifdef CONFIG_NET_CLS_ACT
- if(tb[TCA_FW_ACT-1]) {
- act = kmalloc(sizeof(*act),GFP_KERNEL);
- if (NULL == act)
- return -ENOMEM;
- memset(act,0,sizeof(*act));
- ret = tcf_action_init(tb[TCA_FW_ACT-1], tca[TCA_RATE-1],act,NULL,TCA_ACT_NOREPLACE,TCA_ACT_BIND);
- if (0 > ret) {
- tcf_action_destroy(act,TCA_ACT_UNBIND);
- return ret;
- }
- f->action= act;
- }
-#ifdef CONFIG_NET_CLS_IND
- if(tb[TCA_FW_INDEV-1]) {
- struct rtattr *idev = tb[TCA_FW_INDEV-1];
- if (RTA_PAYLOAD(idev) >= IFNAMSIZ) {
- printk("cls_fw: bad indev name %s\n",(char*)RTA_DATA(idev));
- err = -EINVAL;
- goto errout;
- }
- memset(f->indev,0,IFNAMSIZ);
- sprintf(f->indev, "%s", (char*)RTA_DATA(idev));
- }
-#endif
-#else
-#ifdef CONFIG_NET_CLS_POLICE
- if (tb[TCA_FW_POLICE-1])
- f->police = tcf_police_locate(tb[TCA_FW_POLICE-1], tca[TCA_RATE-1]);
-#endif
-#endif
+ err = fw_change_attrs(tp, f, tb, tca, base);
+ if (err < 0)
+ goto errout;
f->next = head->ht[fw_hash(handle)];
tcf_tree_lock(tp);
@@ -419,7 +338,7 @@ static void fw_walk(struct tcf_proto *tp, struct tcf_walker *arg)
}
if (arg->fn(tp, (unsigned long)f, arg) < 0) {
arg->stop = 1;
- break;
+ return;
}
arg->count++;
}
@@ -438,15 +357,15 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
t->tcm_handle = f->id;
- if (!f->res.classid
+ if (!f->res.classid
#ifdef CONFIG_NET_CLS_ACT
- && !f->action
+ && !f->action
#else
#ifdef CONFIG_NET_CLS_POLICE
- && !f->police
+ && !f->police
#endif
#endif
- )
+ )
return skb->len;
rta = (struct rtattr*)b;
@@ -454,65 +373,35 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
if (f->res.classid)
RTA_PUT(skb, TCA_FW_CLASSID, 4, &f->res.classid);
-#ifdef CONFIG_NET_CLS_ACT
- /* again for backward compatible mode - we want
- * to work with both old and new modes of entering
- * tc data even if iproute2 was newer - jhs
- */
- if (f->action) {
- struct rtattr * p_rta = (struct rtattr*)skb->tail;
-
- if (f->action->type != TCA_OLD_COMPAT) {
- RTA_PUT(skb, TCA_FW_ACT, 0, NULL);
- if (tcf_action_dump(skb,f->action,0,0) < 0) {
- goto rtattr_failure;
- }
- } else {
- RTA_PUT(skb, TCA_FW_POLICE, 0, NULL);
- if (tcf_action_dump_old(skb,f->action,0,0) < 0) {
- goto rtattr_failure;
- }
- }
-
- p_rta->rta_len = skb->tail - (u8*)p_rta;
- }
#ifdef CONFIG_NET_CLS_IND
- if(strlen(f->indev)) {
- struct rtattr * p_rta = (struct rtattr*)skb->tail;
+ if (strlen(f->indev))
RTA_PUT(skb, TCA_FW_INDEV, IFNAMSIZ, f->indev);
- p_rta->rta_len = skb->tail - (u8*)p_rta;
- }
-#endif
-#else
+#endif /* CONFIG_NET_CLS_IND */
+#ifdef CONFIG_NET_CLS_ACT
+ if (tcf_dump_act(skb, f->action, TCA_FW_ACT, TCA_FW_POLICE) < 0)
+ goto rtattr_failure;
+#else /* CONFIG_NET_CLS_ACT */
#ifdef CONFIG_NET_CLS_POLICE
- if (f->police) {
- struct rtattr * p_rta = (struct rtattr*)skb->tail;
-
- RTA_PUT(skb, TCA_FW_POLICE, 0, NULL);
-
- if (tcf_police_dump(skb, f->police) < 0)
- goto rtattr_failure;
-
- p_rta->rta_len = skb->tail - (u8*)p_rta;
- }
-#endif
-#endif
+ if (tcf_dump_police(skb, f->police, TCA_FW_POLICE) < 0)
+ goto rtattr_failure;
+#endif /* CONFIG_NET_CLS_POLICE */
+#endif /* CONFIG_NET_CLS_ACT */
rta->rta_len = skb->tail - b;
#ifdef CONFIG_NET_CLS_ACT
- if (f->action && f->action->type == TCA_OLD_COMPAT) {
- if (tcf_action_copy_stats(skb,f->action))
- goto rtattr_failure;
- }
-#else
+ if (f->action && f->action->type == TCA_OLD_COMPAT) {
+ if (tcf_action_copy_stats(skb,f->action))
+ goto rtattr_failure;
+ }
+#else /* CONFIG_NET_CLS_ACT */
#ifdef CONFIG_NET_CLS_POLICE
if (f->police) {
if (qdisc_copy_stats(skb, &f->police->stats,
- f->police->stats_lock))
+ f->police->stats_lock))
goto rtattr_failure;
}
-#endif
-#endif
+#endif /* CONFIG_NET_CLS_POLICE */
+#endif /* CONFIG_NET_CLS_ACT */
return skb->len;
rtattr_failure:
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index a39e85264276..f595415d0bac 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -292,11 +292,8 @@ static void route4_destroy(struct tcf_proto *tp)
struct route4_filter *f;
while ((f = b->ht[h2]) != NULL) {
- unsigned long cl;
-
b->ht[h2] = f->next;
- if ((cl = __cls_set_class(&f->res.class, 0)) != 0)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+ tcf_unbind_filter(tp, &f->res);
#ifdef CONFIG_NET_CLS_POLICE
tcf_police_release(f->police,TCA_ACT_UNBIND);
#endif
@@ -325,17 +322,12 @@ static int route4_delete(struct tcf_proto *tp, unsigned long arg)
for (fp = &b->ht[from_hash(h>>16)]; *fp; fp = &(*fp)->next) {
if (*fp == f) {
- unsigned long cl;
-
tcf_tree_lock(tp);
*fp = f->next;
tcf_tree_unlock(tp);
route4_reset_fastmap(tp->q->dev, head, f->id);
-
- if ((cl = cls_set_class(tp, &f->res.class, 0)) != 0)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
-
+ tcf_unbind_filter(tp, &f->res);
#ifdef CONFIG_NET_CLS_POLICE
tcf_police_release(f->police,TCA_ACT_UNBIND);
#endif
@@ -379,27 +371,18 @@ static int route4_change(struct tcf_proto *tp, unsigned long base,
return -EINVAL;
if ((f = (struct route4_filter*)*arg) != NULL) {
- /* Node exists: adjust only classid */
-
if (f->handle != handle && handle)
return -EINVAL;
if (tb[TCA_ROUTE4_CLASSID-1]) {
- unsigned long cl;
-
f->res.classid = *(u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID-1]);
- cl = cls_set_class(tp, &f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid));
- if (cl)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+ tcf_bind_filter(tp, &f->res, base);
}
#ifdef CONFIG_NET_CLS_POLICE
if (tb[TCA_ROUTE4_POLICE-1]) {
- struct tcf_police *police = tcf_police_locate(tb[TCA_ROUTE4_POLICE-1], tca[TCA_RATE-1]);
-
- tcf_tree_lock(tp);
- police = xchg(&f->police, police);
- tcf_tree_unlock(tp);
-
- tcf_police_release(police,TCA_ACT_UNBIND);
+ err = tcf_change_police(tp, &f->police,
+ tb[TCA_ROUTE4_POLICE-1], tca[TCA_RATE-1]);
+ if (err < 0)
+ return err;
}
#endif
return 0;
@@ -492,10 +475,10 @@ static int route4_change(struct tcf_proto *tp, unsigned long base,
goto errout;
}
- cls_set_class(tp, &f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid));
+ tcf_bind_filter(tp, &f->res, base);
#ifdef CONFIG_NET_CLS_POLICE
if (tb[TCA_ROUTE4_POLICE-1])
- f->police = tcf_police_locate(tb[TCA_ROUTE4_POLICE-1], tca[TCA_RATE-1]);
+ tcf_change_police(tp, &f->police, tb[TCA_ROUTE4_POLICE-1], tca[TCA_RATE-1]);
#endif
f->next = f1;
@@ -538,7 +521,7 @@ static void route4_walk(struct tcf_proto *tp, struct tcf_walker *arg)
}
if (arg->fn(tp, (unsigned long)f, arg) < 0) {
arg->stop = 1;
- break;
+ return;
}
arg->count++;
}
@@ -577,16 +560,8 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh,
if (f->res.classid)
RTA_PUT(skb, TCA_ROUTE4_CLASSID, 4, &f->res.classid);
#ifdef CONFIG_NET_CLS_POLICE
- if (f->police) {
- struct rtattr * p_rta = (struct rtattr*)skb->tail;
-
- RTA_PUT(skb, TCA_ROUTE4_POLICE, 0, NULL);
-
- if (tcf_police_dump(skb, f->police) < 0)
- goto rtattr_failure;
-
- p_rta->rta_len = skb->tail - (u8*)p_rta;
- }
+ if (tcf_dump_police(skb, f->police, TCA_ROUTE4_POLICE) < 0)
+ goto rtattr_failure;
#endif
rta->rta_len = skb->tail - b;
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index f70fad175a6f..7e11260b6930 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -272,11 +272,8 @@ static void rsvp_destroy(struct tcf_proto *tp)
struct rsvp_filter *f;
while ((f = s->ht[h2]) != NULL) {
- unsigned long cl;
-
s->ht[h2] = f->next;
- if ((cl = __cls_set_class(&f->res.class, 0)) != 0)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+ tcf_unbind_filter(tp, &f->res);
#ifdef CONFIG_NET_CLS_POLICE
tcf_police_release(f->police,TCA_ACT_UNBIND);
#endif
@@ -299,16 +296,10 @@ static int rsvp_delete(struct tcf_proto *tp, unsigned long arg)
for (fp = &s->ht[(h>>8)&0xFF]; *fp; fp = &(*fp)->next) {
if (*fp == f) {
- unsigned long cl;
-
-
tcf_tree_lock(tp);
*fp = f->next;
tcf_tree_unlock(tp);
-
- if ((cl = cls_set_class(tp, &f->res.class, 0)) != 0)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
-
+ tcf_unbind_filter(tp, &f->res);
#ifdef CONFIG_NET_CLS_POLICE
tcf_police_release(f->police,TCA_ACT_UNBIND);
#endif
@@ -437,22 +428,15 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base,
if (f->handle != handle && handle)
return -EINVAL;
if (tb[TCA_RSVP_CLASSID-1]) {
- unsigned long cl;
-
f->res.classid = *(u32*)RTA_DATA(tb[TCA_RSVP_CLASSID-1]);
- cl = cls_set_class(tp, &f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid));
- if (cl)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+ tcf_bind_filter(tp, &f->res, base);
}
#ifdef CONFIG_NET_CLS_POLICE
if (tb[TCA_RSVP_POLICE-1]) {
- struct tcf_police *police = tcf_police_locate(tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]);
-
- tcf_tree_lock(tp);
- police = xchg(&f->police, police);
- tcf_tree_unlock(tp);
-
- tcf_police_release(police,TCA_ACT_UNBIND);
+ err = tcf_change_police(tp, &f->police,
+ tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]);
+ if (err < 0)
+ return err;
}
#endif
return 0;
@@ -531,10 +515,10 @@ insert:
f->sess = s;
if (f->tunnelhdr == 0)
- cls_set_class(tp, &f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid));
+ tcf_bind_filter(tp, &f->res, base);
#ifdef CONFIG_NET_CLS_POLICE
if (tb[TCA_RSVP_POLICE-1])
- f->police = tcf_police_locate(tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]);
+ tcf_change_police(tp, &f->police, tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]);
#endif
for (fp = &s->ht[h2]; *fp; fp = &(*fp)->next)
@@ -601,7 +585,7 @@ static void rsvp_walk(struct tcf_proto *tp, struct tcf_walker *arg)
}
if (arg->fn(tp, (unsigned long)f, arg) < 0) {
arg->stop = 1;
- break;
+ return;
}
arg->count++;
}
@@ -641,16 +625,8 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
if (((f->handle>>8)&0xFF) != 16)
RTA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src);
#ifdef CONFIG_NET_CLS_POLICE
- if (f->police) {
- struct rtattr * p_rta = (struct rtattr*)skb->tail;
-
- RTA_PUT(skb, TCA_RSVP_POLICE, 0, NULL);
-
- if (tcf_police_dump(skb, f->police) < 0)
- goto rtattr_failure;
-
- p_rta->rta_len = skb->tail - (u8*)p_rta;
- }
+ if (tcf_dump_police(skb, f->police, TCA_RSVP_POLICE) < 0)
+ goto rtattr_failure;
#endif
rta->rta_len = skb->tail - b;
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index f8c58fb573ce..709cf821252a 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -165,7 +165,6 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg)
struct tcindex_data *p = PRIV(tp);
struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg;
struct tcindex_filter *f = NULL;
- unsigned long cl;
DPRINTK("tcindex_delete(tp %p,arg 0x%lx),p %p,f %p\n",tp,arg,p,f);
if (p->perfect) {
@@ -187,9 +186,7 @@ found:
*walk = f->next;
tcf_tree_unlock(tp);
}
- cl = __cls_set_class(&r->res.class,0);
- if (cl)
- tp->q->ops->cl_ops->unbind_tcf(tp->q,cl);
+ tcf_unbind_filter(tp, &r->res);
#ifdef CONFIG_NET_CLS_POLICE
tcf_police_release(r->police, TCA_ACT_UNBIND);
#endif
@@ -313,28 +310,19 @@ static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle,
}
DPRINTK("r=%p\n",r);
if (tb[TCA_TCINDEX_CLASSID-1]) {
- unsigned long cl = cls_set_class(tp,&r->res.class,0);
-
- if (cl)
- tp->q->ops->cl_ops->unbind_tcf(tp->q,cl);
r->res.classid = *(__u32 *) RTA_DATA(tb[TCA_TCINDEX_CLASSID-1]);
- r->res.class = tp->q->ops->cl_ops->bind_tcf(tp->q,base,
- r->res.classid);
+ tcf_bind_filter(tp, &r->res, base);
+
if (!r->res.class) {
r->res.classid = 0;
return -ENOENT;
}
- }
+ }
#ifdef CONFIG_NET_CLS_POLICE
- {
- struct tcf_police *police;
-
- police = tb[TCA_TCINDEX_POLICE-1] ?
- tcf_police_locate(tb[TCA_TCINDEX_POLICE-1],NULL) : NULL;
- tcf_tree_lock(tp);
- police = xchg(&r->police,police);
- tcf_tree_unlock(tp);
- tcf_police_release(police,TCA_ACT_UNBIND);
+ if (tb[TCA_TCINDEX_POLICE-1]) {
+ int err = tcf_change_police(tp, &r->police, tb[TCA_TCINDEX_POLICE-1], NULL);
+ if (err < 0)
+ return err;
}
#endif
if (r != &new_filter_result)
@@ -459,14 +447,8 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
if (r->res.class)
RTA_PUT(skb, TCA_TCINDEX_CLASSID, 4, &r->res.classid);
#ifdef CONFIG_NET_CLS_POLICE
- if (r->police) {
- struct rtattr *p_rta = (struct rtattr *) skb->tail;
-
- RTA_PUT(skb,TCA_TCINDEX_POLICE,0,NULL);
- if (tcf_police_dump(skb,r->police) < 0)
- goto rtattr_failure;
- p_rta->rta_len = skb->tail-(u8 *) p_rta;
- }
+ if (tcf_dump_police(skb, r->police, TCA_TCINDEX_POLICE) < 0)
+ goto rtattr_failure;
#endif
}
rta->rta_len = skb->tail-b;
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index c8e11345f308..71330bb41619 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -156,18 +156,9 @@ check_terminal:
*res = n->res;
#ifdef CONFIG_NET_CLS_IND
- /* yes, i know it sucks but the feature is
- ** optional dammit! - JHS */
- if (0 != n->indev[0]) {
- if (NULL == skb->input_dev) {
- n = n->next;
- goto next_knode;
- } else {
- if (0 != strcmp(n->indev, skb->input_dev->name)) {
- n = n->next;
- goto next_knode;
- }
- }
+ if (!tcf_match_indev(skb, n->indev)) {
+ n = n->next;
+ goto next_knode;
}
#endif
#ifdef CONFIG_CLS_U32_PERF
@@ -346,10 +337,7 @@ static int u32_init(struct tcf_proto *tp)
static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n)
{
- unsigned long cl;
-
- if ((cl = __cls_set_class(&n->res.class, 0)) != 0)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+ tcf_unbind_filter(tp, &n->res);
#ifdef CONFIG_NET_CLS_ACT
if (n->action) {
tcf_action_destroy(n->action, TCA_ACT_UNBIND);
@@ -495,15 +483,11 @@ static u32 gen_new_kid(struct tc_u_hnode *ht, u32 handle)
return handle|(i>0xFFF ? 0xFFF : i);
}
-static int u32_set_parms(struct Qdisc *q, unsigned long base,
+static int u32_set_parms(struct tcf_proto *tp, unsigned long base,
struct tc_u_hnode *ht,
struct tc_u_knode *n, struct rtattr **tb,
struct rtattr *est)
{
-#ifdef CONFIG_NET_CLS_ACT
- struct tc_action *act = NULL;
- int ret;
-#endif
if (tb[TCA_U32_LINK-1]) {
u32 handle = *(u32*)RTA_DATA(tb[TCA_U32_LINK-1]);
struct tc_u_hnode *ht_down = NULL;
@@ -519,88 +503,43 @@ static int u32_set_parms(struct Qdisc *q, unsigned long base,
ht_down->refcnt++;
}
- sch_tree_lock(q);
+ tcf_tree_lock(tp);
ht_down = xchg(&n->ht_down, ht_down);
- sch_tree_unlock(q);
+ tcf_tree_unlock(tp);
if (ht_down)
ht_down->refcnt--;
}
if (tb[TCA_U32_CLASSID-1]) {
- unsigned long cl;
-
n->res.classid = *(u32*)RTA_DATA(tb[TCA_U32_CLASSID-1]);
- sch_tree_lock(q);
- cl = __cls_set_class(&n->res.class, q->ops->cl_ops->bind_tcf(q, base, n->res.classid));
- sch_tree_unlock(q);
- if (cl)
- q->ops->cl_ops->unbind_tcf(q, cl);
+ tcf_bind_filter(tp, &n->res, base);
}
#ifdef CONFIG_NET_CLS_ACT
- /*backward compatibility */
- if (tb[TCA_U32_POLICE-1])
- {
- act = kmalloc(sizeof(*act),GFP_KERNEL);
- if (NULL == act)
- return -ENOMEM;
-
- memset(act,0,sizeof(*act));
- ret = tcf_action_init_1(tb[TCA_U32_POLICE-1], est,act,"police", TCA_ACT_NOREPLACE, TCA_ACT_BIND);
- if (0 > ret){
- tcf_action_destroy(act, TCA_ACT_UNBIND);
- return ret;
- }
- act->type = TCA_OLD_COMPAT;
-
- sch_tree_lock(q);
- act = xchg(&n->action, act);
- sch_tree_unlock(q);
-
- tcf_action_destroy(act, TCA_ACT_UNBIND);
-
+ if (tb[TCA_U32_POLICE-1]) {
+ int err = tcf_change_act_police(tp, &n->action, tb[TCA_U32_POLICE-1], est);
+ if (err < 0)
+ return err;
}
- if(tb[TCA_U32_ACT-1]) {
- act = kmalloc(sizeof(*act),GFP_KERNEL);
- if (NULL == act)
- return -ENOMEM;
- memset(act,0,sizeof(*act));
- ret = tcf_action_init(tb[TCA_U32_ACT-1], est,act,NULL,TCA_ACT_NOREPLACE, TCA_ACT_BIND);
- if (0 > ret) {
- tcf_action_destroy(act, TCA_ACT_UNBIND);
- return ret;
- }
-
- sch_tree_lock(q);
- act = xchg(&n->action, act);
- sch_tree_unlock(q);
-
- tcf_action_destroy(act, TCA_ACT_UNBIND);
+ if (tb[TCA_U32_ACT-1]) {
+ int err = tcf_change_act(tp, &n->action, tb[TCA_U32_ACT-1], est);
+ if (err < 0)
+ return err;
}
-
-
#else
#ifdef CONFIG_NET_CLS_POLICE
if (tb[TCA_U32_POLICE-1]) {
- struct tcf_police *police = tcf_police_locate(tb[TCA_U32_POLICE-1], est);
- sch_tree_lock(q);
- police = xchg(&n->police, police);
- sch_tree_unlock(q);
- tcf_police_release(police, TCA_ACT_UNBIND);
+ int err = tcf_change_police(tp, &n->police, tb[TCA_U32_POLICE-1], est);
+ if (err < 0)
+ return err;
}
#endif
#endif
#ifdef CONFIG_NET_CLS_IND
- n->indev[0] = 0;
- if(tb[TCA_U32_INDEV-1]) {
- struct rtattr *input_dev = tb[TCA_U32_INDEV-1];
- if (RTA_PAYLOAD(input_dev) >= IFNAMSIZ) {
- printk("cls_u32: bad indev name %s\n",(char*)RTA_DATA(input_dev));
- /* should we clear state first? */
- return -EINVAL;
- }
- sprintf(n->indev, "%s", (char*)RTA_DATA(input_dev));
- printk("got IND %s\n",n->indev);
+ if (tb[TCA_U32_INDEV-1]) {
+ int err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]);
+ if (err < 0)
+ return err;
}
#endif
@@ -630,7 +569,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
if (TC_U32_KEY(n->handle) == 0)
return -EINVAL;
- return u32_set_parms(tp->q, base, n->ht_up, n, tb, tca[TCA_RATE-1]);
+ return u32_set_parms(tp, base, n->ht_up, n, tb, tca[TCA_RATE-1]);
}
if (tb[TCA_U32_DIVISOR-1]) {
@@ -718,7 +657,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
}
n->fshift = i;
}
- err = u32_set_parms(tp->q, base, ht, n, tb, tca[TCA_RATE-1]);
+ err = u32_set_parms(tp, base, ht, n, tb, tca[TCA_RATE-1]);
if (err == 0) {
struct tc_u_knode **ins;
for (ins = &ht->ht[TC_U32_HASH(handle)]; *ins; ins = &(*ins)->next)
@@ -806,49 +745,18 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
if (n->ht_down)
RTA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle);
#ifdef CONFIG_NET_CLS_ACT
- /* again for backward compatible mode - we want
- * to work with both old and new modes of entering
- * tc data even if iproute2 was newer - jhs
- */
- if (n->action) {
- struct rtattr * p_rta = (struct rtattr*)skb->tail;
-
- if (n->action->type != TCA_OLD_COMPAT) {
- RTA_PUT(skb, TCA_U32_ACT, 0, NULL);
- if (tcf_action_dump(skb,n->action, 0, 0) < 0) {
- goto rtattr_failure;
- }
- } else {
- RTA_PUT(skb, TCA_U32_POLICE, 0, NULL);
- if (tcf_action_dump_old(skb,n->action,0,0) < 0) {
- goto rtattr_failure;
- }
- }
-
- p_rta->rta_len = skb->tail - (u8*)p_rta;
- }
-
+ if (tcf_dump_act(skb, n->action, TCA_U32_ACT, TCA_U32_POLICE) < 0)
+ goto rtattr_failure;
#else
#ifdef CONFIG_NET_CLS_POLICE
- if (n->police) {
- struct rtattr * p_rta = (struct rtattr*)skb->tail;
- RTA_PUT(skb, TCA_U32_POLICE, 0, NULL);
-
- if (tcf_police_dump(skb, n->police) < 0)
- goto rtattr_failure;
-
- p_rta->rta_len = skb->tail - (u8*)p_rta;
-
- }
+ if (tcf_dump_police(skb, n->police, TCA_U32_POLICE) < 0)
+ goto rtattr_failure;
#endif
#endif
#ifdef CONFIG_NET_CLS_IND
- if(strlen(n->indev)) {
- struct rtattr * p_rta = (struct rtattr*)skb->tail;
+ if(strlen(n->indev))
RTA_PUT(skb, TCA_U32_INDEV, IFNAMSIZ, n->indev);
- p_rta->rta_len = skb->tail - (u8*)p_rta;
- }
#endif
#ifdef CONFIG_CLS_U32_PERF
RTA_PUT(skb, TCA_U32_PCNT,
diff --git a/net/sched/ipt.c b/net/sched/ipt.c
new file mode 100644
index 000000000000..4938cd95e693
--- /dev/null
+++ b/net/sched/ipt.c
@@ -0,0 +1,392 @@
+/*
+ * net/sched/ipt.c iptables target interface
+ *
+ *TODO: Add other tables. For now we only support the ipv4 table targets
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Copyright: Jamal Hadi Salim (2002-4)
+ */
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/in.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <net/sock.h>
+#include <net/pkt_sched.h>
+#include <linux/tc_act/tc_ipt.h>
+#include <net/tc_act/tc_ipt.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+
+/* use generic hash table */
+#define MY_TAB_SIZE 16
+#define MY_TAB_MASK 15
+
+u32 idx_gen;
+static struct tcf_ipt *tcf_ipt_ht[MY_TAB_SIZE];
+/* ipt hash table lock */
+static rwlock_t ipt_lock = RW_LOCK_UNLOCKED;
+
+/* ovewrride the defaults */
+#define tcf_st tcf_ipt
+#define tcf_t_lock ipt_lock
+#define tcf_ht tcf_ipt_ht
+
+#include <net/pkt_act.h>
+
+static inline int
+init_targ(struct tcf_ipt *p)
+{
+ struct ipt_target *target;
+ int ret = 0;
+ struct ipt_entry_target *t = p->t;
+ target = __ipt_find_target_lock(t->u.user.name, &ret);
+
+ if (!target) {
+ printk("init_targ: Failed to find %s\n",
+ t->u.kernel.target->name);
+ return -1;
+ }
+
+ DPRINTK("init_targ: found %s\n", target->name);
+ /* we really need proper ref counting
+ seems to be only needed for modules?? Talk to laforge */
+/* if (target->me)
+ __MOD_INC_USE_COUNT(target->me);
+*/
+ t->u.kernel.target = target;
+
+ __ipt_mutex_up();
+
+ if (t->u.kernel.target->checkentry
+ && !t->u.kernel.target->checkentry(p->tname, NULL, t->data,
+ t->u.target_size
+ - sizeof (*t), p->hook)) {
+/* if (t->u.kernel.target->me)
+ __MOD_DEC_USE_COUNT(t->u.kernel.target->me);
+*/
+ DPRINTK("ip_tables: check failed for `%s'.\n",
+ t->u.kernel.target->name);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+int
+tcf_ipt_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, int ovr, int bind)
+{
+ struct ipt_entry_target *t;
+ unsigned h;
+ struct rtattr *tb[TCA_IPT_MAX];
+ struct tcf_ipt *p;
+ int ret = 0;
+ u32 index = 0;
+ u32 hook = 0;
+
+ if (NULL == a || NULL == rta ||
+ (rtattr_parse(tb, TCA_IPT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) <
+ 0)) {
+ return -1;
+ }
+
+
+ if (tb[TCA_IPT_INDEX - 1]) {
+ index = *(u32 *) RTA_DATA(tb[TCA_IPT_INDEX - 1]);
+ DPRINTK("ipt index %d\n", index);
+ }
+
+ if (index && (p = tcf_hash_lookup(index)) != NULL) {
+ a->priv = (void *) p;
+ spin_lock(&p->lock);
+ if (bind) {
+ p->bindcnt += 1;
+ p->refcnt += 1;
+ }
+ if (ovr) {
+ goto override;
+ }
+ spin_unlock(&p->lock);
+ return ret;
+ }
+
+ if (NULL == tb[TCA_IPT_TARG - 1] || NULL == tb[TCA_IPT_HOOK - 1]) {
+ return -1;
+ }
+
+ p = kmalloc(sizeof (*p), GFP_KERNEL);
+ if (p == NULL)
+ return -1;
+
+ memset(p, 0, sizeof (*p));
+ p->refcnt = 1;
+ ret = 1;
+ spin_lock_init(&p->lock);
+ p->stats_lock = &p->lock;
+ if (bind)
+ p->bindcnt = 1;
+
+override:
+ hook = *(u32 *) RTA_DATA(tb[TCA_IPT_HOOK - 1]);
+
+ t = (struct ipt_entry_target *) RTA_DATA(tb[TCA_IPT_TARG - 1]);
+
+ p->t = kmalloc(t->u.target_size, GFP_KERNEL);
+ if (p->t == NULL) {
+ if (ovr) {
+ printk("ipt policy messed up \n");
+ spin_unlock(&p->lock);
+ return -1;
+ }
+ kfree(p);
+ return -1;
+ }
+
+ memcpy(p->t, RTA_DATA(tb[TCA_IPT_TARG - 1]), t->u.target_size);
+ DPRINTK(" target NAME %s size %d data[0] %x data[1] %x\n",
+ t->u.user.name, t->u.target_size, t->data[0], t->data[1]);
+
+ p->tname = kmalloc(IFNAMSIZ, GFP_KERNEL);
+
+ if (p->tname == NULL) {
+ if (ovr) {
+ printk("ipt policy messed up 2 \n");
+ spin_unlock(&p->lock);
+ return -1;
+ }
+ kfree(p->t);
+ kfree(p);
+ return -1;
+ } else {
+ int csize = IFNAMSIZ - 1;
+
+ memset(p->tname, 0, IFNAMSIZ);
+ if (tb[TCA_IPT_TABLE - 1]) {
+ if (strlen((char *) RTA_DATA(tb[TCA_IPT_TABLE - 1])) <
+ csize)
+ csize = strlen(RTA_DATA(tb[TCA_IPT_TABLE - 1]));
+ strncpy(p->tname, RTA_DATA(tb[TCA_IPT_TABLE - 1]),
+ csize);
+ DPRINTK("table name %s\n", p->tname);
+ } else {
+ strncpy(p->tname, "mangle", 1 + strlen("mangle"));
+ }
+ }
+
+ if (0 > init_targ(p)) {
+ if (ovr) {
+ printk("ipt policy messed up 2 \n");
+ spin_unlock(&p->lock);
+ return -1;
+ }
+ kfree(p->tname);
+ kfree(p->t);
+ kfree(p);
+ return -1;
+ }
+
+ if (ovr) {
+ spin_unlock(&p->lock);
+ return -1;
+ }
+
+ p->index = index ? : tcf_hash_new_index();
+
+ p->tm.lastuse = jiffies;
+ /*
+ p->tm.expires = jiffies;
+ */
+ p->tm.install = jiffies;
+#ifdef CONFIG_NET_ESTIMATOR
+ if (est) {
+ qdisc_new_estimator(&p->stats, p->stats_lock, est);
+ }
+#endif
+ h = tcf_hash(p->index);
+ write_lock_bh(&ipt_lock);
+ p->next = tcf_ipt_ht[h];
+ tcf_ipt_ht[h] = p;
+ write_unlock_bh(&ipt_lock);
+ a->priv = (void *) p;
+ return ret;
+
+}
+
+int
+tcf_ipt_cleanup(struct tc_action *a, int bind)
+{
+ struct tcf_ipt *p;
+ p = PRIV(a,ipt);
+ if (NULL != p)
+ return tcf_hash_release(p, bind);
+ return 0;
+}
+
+int
+tcf_ipt(struct sk_buff **pskb, struct tc_action *a)
+{
+ int ret = 0, result = 0;
+ struct tcf_ipt *p;
+ struct sk_buff *skb = *pskb;
+
+ p = PRIV(a,ipt);
+
+ if (NULL == p || NULL == skb) {
+ return -1;
+ }
+
+ spin_lock(&p->lock);
+
+ p->tm.lastuse = jiffies;
+ p->stats.bytes += skb->len;
+ p->stats.packets++;
+
+ if (skb_cloned(skb) ) {
+ if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
+ return -1;
+ }
+ }
+ /* yes, we have to worry about both in and out dev
+ worry later - danger - this API seems to have changed
+ from earlier kernels */
+
+ ret = p->t->u.kernel.target->target(&skb, skb->dev, NULL,
+ p->hook, p->t->data, (void *)NULL);
+ switch (ret) {
+ case NF_ACCEPT:
+ result = TC_ACT_OK;
+ break;
+ case NF_DROP:
+ result = TC_ACT_SHOT;
+ p->stats.drops++;
+ break;
+ case IPT_CONTINUE:
+ result = TC_ACT_PIPE;
+ break;
+ default:
+ if (net_ratelimit())
+ printk("Bogus netfilter code %d assume ACCEPT\n", ret);
+ result = TC_POLICE_OK;
+ break;
+ }
+ spin_unlock(&p->lock);
+ return result;
+
+}
+
+int
+tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
+{
+ struct ipt_entry_target *t;
+ struct tcf_t tm;
+ struct tc_cnt c;
+ unsigned char *b = skb->tail;
+
+ struct tcf_ipt *p;
+
+ p = PRIV(a,ipt);
+ if (NULL == p) {
+ printk("BUG: tcf_ipt_dump called with NULL params\n");
+ goto rtattr_failure;
+ }
+ /* for simple targets kernel size == user size
+ ** user name = target name
+ ** for foolproof you need to not assume this
+ */
+
+ t = kmalloc(p->t->u.user.target_size, GFP_ATOMIC);
+
+ if (NULL == t)
+ goto rtattr_failure;
+
+ c.bindcnt = p->bindcnt - bind;
+ c.refcnt = p->refcnt - ref;
+ memcpy(t, p->t, p->t->u.user.target_size);
+ strcpy(t->u.user.name, p->t->u.kernel.target->name);
+
+ DPRINTK("\ttcf_ipt_dump tablename %s length %d\n", p->tname,
+ strlen(p->tname));
+ DPRINTK
+ ("\tdump target name %s size %d size user %d data[0] %x data[1] %x\n",
+ p->t->u.kernel.target->name, p->t->u.target_size, p->t->u.user.target_size,
+ p->t->data[0], p->t->data[1]);
+ RTA_PUT(skb, TCA_IPT_TARG, p->t->u.user.target_size, t);
+ RTA_PUT(skb, TCA_IPT_INDEX, 4, &p->index);
+ RTA_PUT(skb, TCA_IPT_HOOK, 4, &p->hook);
+ RTA_PUT(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c);
+ RTA_PUT(skb, TCA_IPT_TABLE, IFNAMSIZ, p->tname);
+ tm.install = jiffies - p->tm.install;
+ tm.lastuse = jiffies - p->tm.lastuse;
+ tm.expires = p->tm.expires;
+ RTA_PUT(skb, TCA_IPT_TM, sizeof (tm), &tm);
+ return skb->len;
+
+ rtattr_failure:
+ skb_trim(skb, b - skb->data);
+ return -1;
+}
+
+int
+tcf_ipt_stats(struct sk_buff *skb, struct tc_action *a)
+{
+ struct tcf_ipt *p;
+ p = PRIV(a,ipt);
+ if (NULL != p)
+ return qdisc_copy_stats(skb, &p->stats, p->stats_lock);
+
+ return 1;
+}
+
+struct tc_action_ops act_ipt_ops = {
+ .next = NULL,
+ .kind = "ipt",
+ .type = TCA_ACT_IPT,
+ .capab = TCA_CAP_NONE,
+ .owner = THIS_MODULE,
+ .act = tcf_ipt,
+ .get_stats = tcf_ipt_stats,
+ .dump = tcf_ipt_dump,
+ .cleanup = tcf_ipt_cleanup,
+ .lookup = tcf_hash_search,
+ .init = tcf_ipt_init,
+ .walk = tcf_generic_walker
+};
+
+MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
+MODULE_DESCRIPTION("Iptables target actions");
+MODULE_LICENSE("GPL");
+
+static int __init
+ipt_init_module(void)
+{
+ return tcf_register_action(&act_ipt_ops);
+}
+
+static void __exit
+ipt_cleanup_module(void)
+{
+ tcf_unregister_action(&act_ipt_ops);
+}
+
+module_init(ipt_init_module);
+module_exit(ipt_cleanup_module);
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 8f2d18263792..36ddfb78d41e 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -98,16 +98,6 @@ static inline void sctp_outq_tail_data(struct sctp_outq *q,
return;
}
-/* Insert a chunk behind chunk 'pos'. */
-static inline void sctp_outq_insert_data(struct sctp_outq *q,
- struct sctp_chunk *ch,
- struct sctp_chunk *pos)
-{
- __skb_insert((struct sk_buff *)ch, (struct sk_buff *)pos->prev,
- (struct sk_buff *)pos, pos->list);
- q->out_qlen += ch->skb->len;
-}
-
/*
* SFR-CACC algorithm:
* D) If count_of_newacks is greater than or equal to 2
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index be33fd881a74..2d8ee7ce0d8f 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -347,6 +347,7 @@ void x25_destroy_socket(struct sock *sk)
/* Defer: outstanding buffers */
sk->sk_timer.expires = jiffies + 10 * HZ;
sk->sk_timer.function = x25_destroy_timer;
+ sk->sk_timer.data = (unsigned long)sk;
add_timer(&sk->sk_timer);
} else {
/* drop last reference so sock_put will free */
diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c
index f58aa65ea965..99af8425fbfc 100644
--- a/net/x25/x25_dev.c
+++ b/net/x25/x25_dev.c
@@ -92,7 +92,9 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb)
/*
x25_transmit_clear_request(nb, lci, 0x0D);
*/
- printk(KERN_DEBUG "x25_receive_data(): unknown frame type %2x\n",frametype);
+
+ if (frametype != X25_CLEAR_CONFIRMATION)
+ printk(KERN_DEBUG "x25_receive_data(): unknown frame type %2x\n",frametype);
return 0;
}
diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c
index ef3140d1041b..64fff05abf8a 100644
--- a/net/x25/x25_proc.c
+++ b/net/x25/x25_proc.c
@@ -32,10 +32,11 @@ static __inline__ struct x25_route *x25_get_route_idx(loff_t pos)
list_for_each(route_entry, &x25_route_list) {
rt = list_entry(route_entry, struct x25_route, node);
- if (--pos)
- break;
+ if (!pos--)
+ goto found;
}
-
+ rt = NULL;
+found:
return rt;
}
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
index 58c7d2671389..58ca6a972c48 100644
--- a/net/xfrm/Kconfig
+++ b/net/xfrm/Kconfig
@@ -1,10 +1,6 @@
#
# XFRM configuration
#
-config XFRM
- bool
- depends on NET
-
config XFRM_USER
tristate "IPsec user configuration interface"
depends on INET && XFRM
diff --git a/net/xfrm/xfrm_export.c b/net/xfrm/xfrm_export.c
index 24dbc9a99b1b..fd34836cdf7f 100644
--- a/net/xfrm/xfrm_export.c
+++ b/net/xfrm/xfrm_export.c
@@ -27,7 +27,6 @@ EXPORT_SYMBOL(__secpath_destroy);
EXPORT_SYMBOL(secpath_dup);
EXPORT_SYMBOL(xfrm_get_acqseq);
EXPORT_SYMBOL(xfrm_parse_spi);
-EXPORT_SYMBOL(xfrm4_rcv);
EXPORT_SYMBOL(xfrm_register_type);
EXPORT_SYMBOL(xfrm_unregister_type);
EXPORT_SYMBOL(xfrm_get_type);