Netdev List
 help / color / mirror / Atom feed
* [PATCH net-2.6.25 1/7] Add the netns_ipv4 struct
From: Pavel Emelyanov @ 2007-12-11 17:45 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List, Linux Containers, devel
In-Reply-To: <475ECC69.1040809@openvz.org>

The ipv4 will store its parameters inside this structure.
This one is empty now, but it will be eventually filled.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

---

diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 18da0af..d04ddf2 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -10,6 +10,7 @@
 
 #include <net/netns/unix.h>
 #include <net/netns/packet.h>
+#include <net/netns/ipv4.h>
 
 struct proc_dir_entry;
 struct net_device;
@@ -46,6 +47,7 @@ struct net {
 
 	struct netns_packet	packet;
 	struct netns_unix	unx;
+	struct netns_ipv4	ipv4;
 };
 
 #ifdef CONFIG_NET
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
new file mode 100644
index 0000000..ce830d5
--- /dev/null
+++ b/include/net/netns/ipv4.h
@@ -0,0 +1,9 @@
+/*
+ * ipv4 in net namespaces
+ */
+
+#ifndef __NETNS_IPV4_H__
+#define __NETNS_IPV4_H__
+struct netns_ipv4 {
+};
+#endif
-- 
1.5.3.4


^ permalink raw reply related

* [PATCH net-2.6.25 0/7] Make ipv4_devconf (all and default) live in net namespaces
From: Pavel Emelyanov @ 2007-12-11 17:44 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List, Linux Containers, devel

The ipv4_devconf_(all) and ipv4_devconf_dflt are currently
global, but should be per-namespace.

This set moves them on the struct net. Or, more precisely,
on the struct netns_ipv4, which in turn is on the struct net.

There are two minor things that are to be done additionally
to this set:

 1. The snmp_seq_show() needs the IPV4_DEVCONF_ALL(FORWARDING)
    value, but since this entry is still global no valid struct 
    net can be get in it, so I use the init_net's one. After 
    snmp is made per-namespace, this will be fixed easily.

 2. The rt_fill_info() needs the IPV4_DEVCONF_ALL(MC_FORWARDING),
    but the routing code is not tuned to work inside namespaces
    yet, so I use the init_net in it as well. Denis is currently
    working on ipv4 routing, so this will be prepared shortly.

Happily, all the other places of devconf-s usage can provide a
struct net pointer.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

^ permalink raw reply

* Re: [PATCH v2] XFRM: assorted IPsec fixups
From: Paul Moore @ 2007-12-11 17:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-audit, selinux
In-Reply-To: <20071211.092126.151519334.davem@davemloft.net>

On Tuesday 11 December 2007 12:21:26 pm David Miller wrote:
> From: Paul Moore <paul.moore@hp.com>
> Date: Tue, 11 Dec 2007 12:15:00 -0500
>
> > I still would like to see the rest of the changes make it into
> > 2.6.25 (the SPI byte order thing is particularly troublesome) so if
> > you don't mind a "v3" I'll respin this patch right now to remove the
> > "sid -> secid" bits.
>
> Technically this could break anything parsing the audit logs, but no
> matter, I'd rather fix this now while we still can.

True, this does change how userspace sees things but I think that any 
userspace code that currently uses this SPI value successfully is either 
lucky or has a workaround/hack in place.

> I would classify the spi endianness bit as a bug fix, could you please
> just split out that fix for net-2.6, then we can make a second patch
> after I rebase net-2.6.25 which can do the rest of your patch sans the
> linux/xfrm.h change?

Sure.  Although that's enough of a change that I'd want to retest the patch a 
bit first.  If I can't get it done today expect something in your inbox 
tomorrow.

Thanks for your patience.

-- 
paul moore
linux security @ hp

^ permalink raw reply

* Re: [PATCH v2] XFRM: assorted IPsec fixups
From: Paul Moore @ 2007-12-11 17:34 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明
  Cc: netdev, linux-audit, selinux
In-Reply-To: <20071211.091957.98044450.yoshfuji@linux-ipv6.org>

On Tuesday 11 December 2007 12:19:57 pm YOSHIFUJI Hideaki / 吉藤英明 wrote:
> Please do not mangle tabs into spaces.

Yes indeed.  Not quite sure what happened there but I just fixed it.

Thanks for pointing that out.

-- 
paul moore
linux security @ hp

^ permalink raw reply

* net-2.6.25 being rebased...
From: David Miller @ 2007-12-11 17:26 UTC (permalink / raw)
  To: netdev


I want to work out all the conflicts now that Linus has pulled
in my most recent batch of fixes.

I hope to have it done in the next hour or so.

Thanks.

^ permalink raw reply

* Re: [PATCH 1/2] add driver for enc28j60 ethernet chip
From: Stephen Hemminger @ 2007-12-11 17:06 UTC (permalink / raw)
  To: Claudio Lanconelli; +Cc: netdev, jgarzik
In-Reply-To: <475EA546.7030202@eptar.com>

On Tue, 11 Dec 2007 15:57:10 +0100
Claudio Lanconelli <lanconelli.claudio@eptar.com> wrote:

> These patches add support for Microchip enc28j60 ethernet chip 
> controlled via SPI.
> I tested it on my custom board (S162) with ARM9 s3c2442 SoC.
> Any comments are welcome.
> 
> Signed-off-by: Claudio Lanconelli <lanconelli.claudio@eptar.com>

General comments:
  * device driver does no carrier detection. This makes it useless
    for bridging, bonding, or any form of failover.

  * use random_ether_addr rather than hardocoding constant mac address

  * use msglevel method (via ethtool) to control debug messages
    rather than kernel configuration. This allows enabling debugging
    without recompilation which is important in distributions.

  * kernel uses u8 rather than uint8_t for byte variables

  * use netdev_priv(netdev) rather than netdev->priv

  * Please add ethtool support

  * Consider using NAPI


Output from checkpatch:
ERROR: do not initialise statics to 0 or NULL
#148: FILE: drivers/net/enc28j60.c:73:
+static int full_duplex = 0;

ERROR: "foo * bar" should be "foo *bar"
#166: FILE: drivers/net/enc28j60.c:91:
+			const uint8_t * data);

ERROR: "foo * bar" should be "foo *bar"
#245: FILE: drivers/net/enc28j60.c:170:
+			 const uint8_t * data)

ERROR: "foo * bar" should be "foo *bar"
#413: FILE: drivers/net/enc28j60.c:338:
+				     uint16_t addr, int len, uint8_t * data)

WARNING: printk() should include KERN_ facility level
#557: FILE: drivers/net/enc28j60.c:482:
+	printk("Cntrl: ECON1 ECON2 ESTAT  EIR  EIE\n");

WARNING: printk() should include KERN_ facility level
#558: FILE: drivers/net/enc28j60.c:483:
+	printk("       0x%02x  ", enc28j60_regb_read(priv, ECON1));

WARNING: printk() should include KERN_ facility level
#564: FILE: drivers/net/enc28j60.c:489:
+	printk("MAC  : MACON1 MACON3 MACON4 MAC-Address\n");

WARNING: printk() should include KERN_ facility level
#565: FILE: drivers/net/enc28j60.c:490:
+	printk("       0x%02x   ", enc28j60_regb_read(priv, MACON1));

WARNING: printk() should include KERN_ facility level
#575: FILE: drivers/net/enc28j60.c:500:
+	printk("Rx   : ERXST  ERXND  ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\n");

WARNING: printk() should include KERN_ facility level
#576: FILE: drivers/net/enc28j60.c:501:
+	printk("       0x%04x ", enc28j60_regw_read(priv, ERXSTL));

WARNING: printk() should include KERN_ facility level
#584: FILE: drivers/net/enc28j60.c:509:
+	printk("Tx   : ETXST  ETXND  MACLCON1 MACLCON2 MAPHSUP\n");

WARNING: printk() should include KERN_ facility level
#585: FILE: drivers/net/enc28j60.c:510:
+	printk("       0x%04x ", enc28j60_regw_read(priv, ETXSTL));

WARNING: braces {} are not necessary for single statement blocks
#601: FILE: drivers/net/enc28j60.c:526:
+	if ((next_packet_ptr - 1 < start) || (next_packet_ptr - 1 > end)) {
+		erxrdpt = end;
+	} else

WARNING: line over 80 characters
#810: FILE: drivers/net/enc28j60.c:735:
+		 "ExCollision: %d, LateCollision: %d, Giant: %d, Underrun: %d\n",

WARNING: line over 80 characters
#961: FILE: drivers/net/enc28j60.c:886:
+						 "enc28j60 RX, max_pk_cnt: %d\n",

WARNING: line over 80 characters
#965: FILE: drivers/net/enc28j60.c:890:
+			 * don't need to clear interrupt flag, automatically done

WARNING: printk() should include KERN_ facility level
#987: FILE: drivers/net/enc28j60.c:912:
+			printk("\n%04x: ", k);

WARNING: labels should not be indented
#1423: FILE: drivers/net/enc28j60.c:1348:
+      error_register:

WARNING: labels should not be indented
#1425: FILE: drivers/net/enc28j60.c:1350:
+      error_irq:

WARNING: labels should not be indented
#1427: FILE: drivers/net/enc28j60.c:1352:
+      error_buf:

WARNING: labels should not be indented
#1429: FILE: drivers/net/enc28j60.c:1354:
+      error_alloc:

total: 4 errors, 17 warnings, 1703 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

My comments:

diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
new file mode 100644
index 0000000..6182473
--- /dev/null
+++ b/drivers/net/enc28j60.c
@@ -0,0 +1,1400 @@
+/*
+ * Microchip ENC28J60 ethernet driver (MAC + PHY)
+ *
+ * Copyright (C) 2007 Eurek srl
+ * Author: Claudio Lanconelli <lanconelli.claudio@eptar.com>
+ * based on enc28j60.c written by David Anders for 2.4 kernel version
+ *
+ * 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.
+ *
+ * $Id: enc28j60.c,v 1.10 2007/12/10 16:59:37 claudio Exp $
+ */
+
+#include <linux/autoconf.h>

Use msglvl instead see netdevice.h

+
+#if CONFIG_ENC28J60_DBGLEVEL > 1
+# define VERBOSE_DEBUG
+#endif
+#if CONFIG_ENC28J60_DBGLEVEL > 0
+# define DEBUG
+#endif
+

...
+
+#define MY_TX_TIMEOUT  ((500*HZ)/1000)

That is a really short TX timeout, should be 2 seconds at least not 1/2 sec.
Having it less than a second causes increased wakeups.

+
+/* Max TX retries in case of collision as suggested by errata datasheet */
+#define MAX_TX_RETRYCOUNT	16
+
+/* Driver local data */
+struct enc28j60_net_local {

Rename something shorter like enc28j60_net or just enc28j60?

+	struct net_device_stats stats;

net_device_stats are now in net_device.

+	struct net_device *netdev;
+	struct spi_device *spi;
+	struct semaphore semlock;	/* protect spi_transfer_buf */
Use mutex (or spin_lock) rather than semaphore

+	uint8_t *spi_transfer_buf;
+	struct sk_buff *tx_skb;
+	struct work_struct tx_work;
+	struct work_struct irq_work;

Not sure why you need to have workqueue's for
tx_work and irq_work, rather than using a spin_lock
and doing directly.

+	int bank;			/* current register bank selected */
bank is really unsigned.
	
+	uint16_t next_pk_ptr;		/* next packet pointer within FIFO */
+	int max_pk_counter;		/* statistics: max packet counter */
+	int tx_retry_count;
these are used as unsigned.

+	int hw_enable;
+};
+
+/* Selects Full duplex vs. Half duplex mode */
+static int full_duplex = 0;

Use ethtool for this.

+
+static int enc28j60_send_packet(struct sk_buff *skb, struct net_device *dev);
+static int enc28j60_net_close(struct net_device *dev);
+static struct net_device_stats *enc28j60_net_get_stats(struct net_device *dev);
+static void enc28j60_set_multicast_list(struct net_device *dev);
+static void enc28j60_net_tx_timeout(struct net_device *ndev);
+
+static int enc28j60_chipset_init(struct net_device *dev);
+static void enc28j60_hw_disable(struct enc28j60_net_local *priv);
+static void enc28j60_hw_enable(struct enc28j60_net_local *priv);
+static void enc28j60_hw_rx(struct enc28j60_net_local *priv);
+static void enc28j60_hw_tx(struct enc28j60_net_local *priv);

If you order functions correctly in code, you don't have to waste lots
of space with all these forward declarations.

...

+			const char *msg);
+
+/*
+ * SPI read buffer
+ * wait for the SPI transfer and copy received data to destination
+ */
+static int
+spi_read_buf(struct enc28j60_net_local *priv, int len, uint8_t *data)
+{
+	uint8_t *rx_buf;
+	uint8_t *tx_buf;
+	struct spi_transfer t;
+	struct spi_message msg;
+	int ret, slen;
+
+	slen = 1;
+	memset(&t, 0, sizeof(t));
+	t.tx_buf = tx_buf = priv->spi_transfer_buf;
+	t.rx_buf = rx_buf = priv->spi_transfer_buf + 4;
+	t.len = slen + len;

If you use structure initializer you can avoid having to do
the memset


+
+	down(&priv->semlock);
+	tx_buf[0] = ENC28J60_READ_BUF_MEM;
+	tx_buf[1] = tx_buf[2] = tx_buf[3] = 0;	/* don't care */
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&t, &msg);
+	ret = spi_sync(priv->spi, &msg);
+	if (ret == 0) {
+		memcpy(data, &rx_buf[slen], len);
+		ret = msg.status;
+	}
+	up(&priv->semlock);
+	if (ret != 0)
+		dev_dbg(&priv->netdev->dev, "%s: failed: ret = %d\n",
+			__FUNCTION__, ret);
+
+	return ret;
+}

...

+/*
+ * Register word read
+ */
+static inline int enc28j60_regw_read(struct enc28j60_net_local *priv,
+				     uint8_t address)
+{

I wouldn't bother marking these as "inline" since the compiler
will decide to inline in most cases.  By telling the compiler to
inline it may generate bigger/slower code.


+	int rl, rh;
+
+	enc28j60_set_bank(priv, address);
+	rl = spi_read_op(priv, ENC28J60_READ_CTRL_REG, address);
+	rh = spi_read_op(priv, ENC28J60_READ_CTRL_REG, address + 1);
+
+	return (rh << 8) | rl;
+}

...

+/*
+ * Program the hardware MAC address from dev->dev_addr.
+ */
+static void enc28j60_set_hw_macaddr(struct enc28j60_net_local *priv)
+{
+	struct net_device *ndev = priv->netdev;
+
+	if (!priv->hw_enable) {
+		/* NOTE: MAC address in ENC28J60 is byte-backward */
+		enc28j60_regb_write(priv, MAADR5, ndev->dev_addr[0]);
+		enc28j60_regb_write(priv, MAADR4, ndev->dev_addr[1]);
+		enc28j60_regb_write(priv, MAADR3, ndev->dev_addr[2]);
+		enc28j60_regb_write(priv, MAADR2, ndev->dev_addr[3]);
+		enc28j60_regb_write(priv, MAADR1, ndev->dev_addr[4]);
+		enc28j60_regb_write(priv, MAADR0, ndev->dev_addr[5]);
+
+		dev_dbg(&ndev->dev,
+			"%s() [%s] Setting MAC address to "
+			"%02x:%02x:%02x:%02x:%02x:%02x\n",
+			__FUNCTION__, ndev->name, ndev->dev_addr[0],
+			ndev->dev_addr[1], ndev->dev_addr[2], ndev->dev_addr[3],
+			ndev->dev_addr[4], ndev->dev_addr[5]);
+	} else
+		dev_dbg(&ndev->dev,
+			"%s() Warning: hw must be disabled to set hw "
+			"Mac address\n", __FUNCTION__);

Should return -EINVAL/-EBUSY/... instead of printing message.

+}
+
+/*
+ * Store the new hardware address in dev->dev_addr, and update the MAC.
+ */
+static int enc28j60_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct sockaddr *address = addr;
+	struct enc28j60_net_local *priv = netdev_priv(dev);
+
+	if (!is_valid_ether_addr(address->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
+	enc28j60_set_hw_macaddr(priv);
+
+	return 0;
+}
...

+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *enc28j60_net_get_stats(struct net_device *dev)
+{
+	struct enc28j60_net_local *priv = netdev_priv(dev);
+
+	return &priv->stats;
+}

If you use dev->stats, then you don't need your own get_stats function.


...

+static int enc28j60_hw_init(struct enc28j60_net_local *priv)
+{
+	uint8_t reg;
+
+	dev_dbg(&priv->spi->dev, "%s() - %s\n",
+		__FUNCTION__, full_duplex ? "FullDuplex" : "HalfDuplex");
+	/* first soft reset the chip */
+	enc28j60_soft_reset(priv);
+
+	dev_vdbg(&priv->spi->dev, "%s() bank0\n", __FUNCTION__);
+
+	/* Clear ECON1 */
+	spi_write_op(priv, ENC28J60_WRITE_CTRL_REG, ECON1, 0x00);
+	priv->bank = 0;
+	priv->hw_enable = 0;
+	priv->tx_retry_count = 0;
+
+	enc28j60_regb_write(priv, ECON2, ECON2_AUTOINC);
+	enc28j60_rxfifo_init(priv, RXSTART_INIT, RXEND_INIT);
+	enc28j60_txfifo_init(priv, TXSTART_INIT, TXEND_INIT);
+
+	/*
+	 * Check the RevID.
+	 * If it's 0x00 or 0xFF probably the enc28j60 is not mounted or
+	 * damaged
+	 */
+	reg = enc28j60_regb_read(priv, EREVID);
+	if (reg == 0x00 || reg == 0xff)
+		return 0;
+
+	dev_vdbg(&priv->spi->dev, "%s() bank1\n", __FUNCTION__);
+
+	/* default filter mode: (unicast OR broadcast) AND crc valid */
+	enc28j60_regb_write(priv, ERXFCON,
+			    ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
+
+	dev_vdbg(&priv->spi->dev, "%s() bank2\n", __FUNCTION__);
+	/* enable MAC receive */
+	enc28j60_regb_write(priv, MACON1,
+			    MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
+	/* enable automatic padding and CRC operations */
+	if (full_duplex) {
+		enc28j60_regb_write(priv, MACON3,
+				    MACON3_PADCFG0 | MACON3_TXCRCEN |
+				    MACON3_FRMLNEN | MACON3_FULDPX);
+		/* set inter-frame gap (non-back-to-back) */
+		enc28j60_regb_write(priv, MAIPGL, 0x12);
+		/* set inter-frame gap (back-to-back) */
+		enc28j60_regb_write(priv, MABBIPG, 0x15);
+	} else {
+		enc28j60_regb_write(priv, MACON3,
+				    MACON3_PADCFG0 | MACON3_TXCRCEN |
+				    MACON3_FRMLNEN);
+		enc28j60_regb_write(priv, MACON4, 1 << 6);	/* DEFER bit */
+		/* set inter-frame gap (non-back-to-back) */
+		enc28j60_regw_write(priv, MAIPGL, 0x0C12);
+		/* set inter-frame gap (back-to-back) */
+		enc28j60_regb_write(priv, MABBIPG, 0x12);
+	}
+	/*
+	 * MACLCON1 (default)
+	 * MACLCON2 (default)
+	 * Set the maximum packet size which the controller will accept
+	 */
+	enc28j60_regw_write(priv, MAMXFLL, MAX_FRAMELEN);
+
+	dev_vdbg(&priv->spi->dev, "%s() bank3\n", __FUNCTION__);
+	/* NOTE: MAC address in ENC28J60 is byte-backward */
+	enc28j60_regb_write(priv, MAADR5, ENC28J60_MAC0);
+	enc28j60_regb_write(priv, MAADR4, ENC28J60_MAC1);
+	enc28j60_regb_write(priv, MAADR3, ENC28J60_MAC2);
+	enc28j60_regb_write(priv, MAADR2, ENC28J60_MAC3);
+	enc28j60_regb_write(priv, MAADR1, ENC28J60_MAC4);
+	enc28j60_regb_write(priv, MAADR0, ENC28J60_MAC5);

Rather than having same address, please use random_ether_addr()
to avoid problems with two devices with same ethernet address.

...

+static int __devinit enc28j60_probe(struct spi_device *spi)
+{
+	struct net_device *dev;
+	struct enc28j60_net_local *priv;
+	int ret = 0;
+
+	dev_dbg(&spi->dev, "%s() start\n", __FUNCTION__);
+
+	dev = alloc_etherdev(sizeof(struct enc28j60_net_local));
+	if (!dev) {
+		ret = -ENOMEM;
+		goto error_alloc;
+	}
+	priv = netdev_priv(dev);
+
+	priv->netdev = dev;	/* priv to netdev reference */
+	priv->spi = spi;	/* priv to spi reference */
+	priv->spi_transfer_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL);

Why not declare the transfer buffer as an array in spi?

+	if (!priv->spi_transfer_buf) {
+		ret = -ENOMEM;
+		goto error_buf;
+	}
+	init_MUTEX(&priv->semlock);
+
+	INIT_WORK(&priv->tx_work, enc28j60_tx_work_handler);
+	INIT_WORK(&priv->irq_work, enc28j60_irq_work_handler);
+	dev_set_drvdata(&spi->dev, priv);	/* spi to priv reference */
+	SET_NETDEV_DEV(dev, &spi->dev);



^ permalink raw reply related

* Re: [PATCH 8/8] [PATCH v2] [CCID3]: Interface CCID3 code with newer Loss Intervals Database
From: Arnaldo Carvalho de Melo @ 2007-12-11 17:22 UTC (permalink / raw)
  To: Gerrit Renker, dccp, netdev
In-Reply-To: <20071211094238.GA9926@gerrit.erg.abdn.ac.uk>

Em Tue, Dec 11, 2007 at 09:42:38AM +0000, Gerrit Renker escreveu:
> | When interfacing we must make sure that ccid3 tfrc_lh_slab is created
> | and then tfrc_li_cachep is not needed. I'm doing this while keeping
> | the structure of the patches, i.e. one introducing, the other removing.
> | But we need to create tfrc_lh_slab if we want the tree to be bisectable.
> | 
> | I'm doing this and keeping your Signed-off-line, please holler if you
> | disagree for some reason.
> If you are just shifting and reordering then that is fine with me. But
> it seems you mean a different patch since in this one there is no slab
> initialisation. 

This time around I'm not doing any reordering, just trying to use your
patches as is, but adding this patch as-is produces a kernel that will
crash, no?

> The loss history and the RX/TX packet history slabs are all created in
> tfrc.c using the three different __init routines of the dccp_tfrc_lib.

Yes, the init routines are called and in turn they create the slab
caches, but up to the patch "[PATCH 8/8] [PATCH v2] [CCID3]: Interface
CCID3 code with newer Loss Intervals Database" the new li slab is not
being created, no? See what I'm talking?

- Arnaldo

^ permalink raw reply

* Re: [PATCH v2] XFRM: assorted IPsec fixups
From: David Miller @ 2007-12-11 17:21 UTC (permalink / raw)
  To: paul.moore; +Cc: netdev, linux-audit, selinux
In-Reply-To: <200712111215.00720.paul.moore@hp.com>

From: Paul Moore <paul.moore@hp.com>
Date: Tue, 11 Dec 2007 12:15:00 -0500

> I still would like to see the rest of the changes make it into
> 2.6.25 (the SPI byte order thing is particularly troublesome) so if
> you don't mind a "v3" I'll respin this patch right now to remove the
> "sid -> secid" bits.

Technically this could break anything parsing the audit logs, but no
matter, I'd rather fix this now while we still can.

I would classify the spi endianness bit as a bug fix, could you please
just split out that fix for net-2.6, then we can make a second patch
after I rebase net-2.6.25 which can do the rest of your patch sans the
linux/xfrm.h change?

Thanks.


^ permalink raw reply

* Re: [PATCH v2] XFRM: assorted IPsec fixups
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2007-12-11 17:19 UTC (permalink / raw)
  To: paul.moore; +Cc: netdev, linux-audit, selinux, yoshfuji
In-Reply-To: <20071211163019.15059.73746.stgit@flek.lan>

In article <20071211163019.15059.73746.stgit@flek.lan> (at Tue, 11 Dec 2007 11:30:19 -0500), Paul Moore <paul.moore@hp.com> says:

> diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
> index 5b860b6..e2a3dd1 100644
> --- a/net/xfrm/xfrm_state.c
> +++ b/net/xfrm/xfrm_state.c
:
> @@ -1994,67 +1995,59 @@ void __init xfrm_state_init(void)
>  static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x,
>  					       struct audit_buffer *audit_buf)
>  {
> -	if (x->security)
> -		audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
> -				 x->security->ctx_alg, x->security->ctx_doi,
> -				 x->security->ctx_str);
> +	struct xfrm_sec_ctx *ctx = x->security;
> +	u32 spi = ntohl(x->id.spi);
>  
> -	switch(x->props.family) {
> -	case AF_INET:
> -		audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
> -				 NIPQUAD(x->props.saddr.a4),
> -				 NIPQUAD(x->id.daddr.a4));
> -		break;
> -	case AF_INET6:
> -		{
> -			struct in6_addr saddr6, daddr6;
> -
> -			memcpy(&saddr6, x->props.saddr.a6,
> -				sizeof(struct in6_addr));
> -			memcpy(&daddr6, x->id.daddr.a6,
> -				sizeof(struct in6_addr));
> -			audit_log_format(audit_buf,
> -					 " src=" NIP6_FMT " dst=" NIP6_FMT,
> -					 NIP6(saddr6), NIP6(daddr6));
> -		}
> -		break;
> -	}
> +        if (ctx)
> +                audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
> +                                 ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
> +
> +        switch(x->props.family) {
> +        case AF_INET:
> +                audit_log_format(audit_buf,
> +				 " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
> +                                 NIPQUAD(x->props.saddr.a4),
> +                                 NIPQUAD(x->id.daddr.a4));
> +                break;
> +        case AF_INET6:
> +		audit_log_format(audit_buf,
> +				 " src=" NIP6_FMT " dst=" NIP6_FMT,
> +				 NIP6(*(struct in6_addr *)x->props.saddr.a6),
> +				 NIP6(*(struct in6_addr *)x->id.daddr.a6));
> +                break;
> +        }
> +
> +	audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
>  }
>  

Please do not mangle tabs into spaces.

--yoshfuji

^ permalink raw reply

* Re: [PATCH v2] XFRM: assorted IPsec fixups
From: Paul Moore @ 2007-12-11 17:15 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-audit, selinux
In-Reply-To: <20071211.090611.59888503.davem@davemloft.net>

On Tuesday 11 December 2007 12:06:11 pm David Miller wrote:
> From: Paul Moore <paul.moore@hp.com>
> Date: Tue, 11 Dec 2007 11:30:19 -0500
>
> Sorry for not pointing this out sooner:

No problem, better late than never ... despite reports to the contrary, 
breaking userspace doesn't excite me as much as it used to ;)

> >  * Convert 'sid' to 'secid'
> >    The 'sid' name is specific to SELinux, 'secid' is the common naming
> >    convention used by the kernel when refering to tokenized LSM labels
>
>  ...
>
> > diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
> > index b58adc5..f75a337 100644
> > --- a/include/linux/xfrm.h
> > +++ b/include/linux/xfrm.h
> > @@ -31,7 +31,7 @@ struct xfrm_sec_ctx {
> >  	__u8	ctx_doi;
> >  	__u8	ctx_alg;
> >  	__u16	ctx_len;
> > -	__u32	ctx_sid;
> > +	__u32	ctx_secid;
> >  	char	ctx_str[0];
> >  };
>
> This datastructure has been exported to userspace, so we really can't
> member names unless it was added only in 2.6.24 and I don't think it
> was.
>
> Correct me if I'm wrong.

Ungh, I didn't think the whole structure was exported to userspace as a single 
binary blob; I'd assumed it was passed back and forth as individual 
fields/attributes.  I guess the old adage about assuming applies here ...

Grrr, that "sid" really bothers me but I guess it's a wart we're going to have 
to live with.  Stoopid userspace :)

I still would like to see the rest of the changes make it into 2.6.25 (the SPI 
byte order thing is particularly troublesome) so if you don't mind a "v3" 
I'll respin this patch right now to remove the "sid -> secid" bits.

-- 
paul moore
linux security @ hp

^ permalink raw reply

* Re: [PATCH 2/2] [IPSEC]: Add ICMP host relookup support
From: David Miller @ 2007-12-11 17:10 UTC (permalink / raw)
  To: herbert; +Cc: netdev
In-Reply-To: <E1J28Nq-0004IU-00@gondolin.me.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 12 Dec 2007 00:55:02 +0800

> diff --git a/include/net/dst.h b/include/net/dst.h
> index aaa2dbb..31468c9 100644
> --- a/include/net/dst.h
> +++ b/include/net/dst.h
> @@ -268,6 +268,7 @@ extern void		dst_init(void);
>  /* Flags for xfrm_lookup flags argument. */
>  enum {
>  	XFRM_LOOKUP_WAIT = 1 << 0,
> +	XFRM_LOOKUP_ICMP = 1 << 1,
>  };
>  
>  struct flowi;

This enumeration doesn't exist in my tree, what are you generating
these patches against?

I'm even reverting the first patch for now until this is figured out.

^ permalink raw reply

* Re: [PATCH 1/2] [IPSEC]: Added xfrm_decode_session_reverse and xfrmX_policy_check_reverse
From: David Miller @ 2007-12-11 17:09 UTC (permalink / raw)
  To: herbert; +Cc: netdev
In-Reply-To: <E1J28Np-0004IK-00@gondolin.me.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 12 Dec 2007 00:55:01 +0800

> [IPSEC]: Added xfrm_decode_session_reverse and xfrmX_policy_check_reverse
> 
> RFC 4301 requires us to relookup ICMP traffic that does not match any
> policies using the reverse of its payload.  This patch adds the functions
> xfrm_decode_session_reverse and xfrmX_policy_check_reverse so we can get
> the reverse flow to perform such a lookup.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

I suspect you generated this against a tree with your async
crypto bits in it, because there were a bunch of line offsets
when I applied this.

Nevertheless I fixed it up, patch applied, thanks.

^ permalink raw reply

* Re: [PATCH v2] XFRM: assorted IPsec fixups
From: David Miller @ 2007-12-11 17:06 UTC (permalink / raw)
  To: paul.moore; +Cc: netdev, linux-audit, selinux
In-Reply-To: <20071211163019.15059.73746.stgit@flek.lan>

From: Paul Moore <paul.moore@hp.com>
Date: Tue, 11 Dec 2007 11:30:19 -0500

Sorry for not pointing this out sooner:

>  * Convert 'sid' to 'secid'
>    The 'sid' name is specific to SELinux, 'secid' is the common naming
>    convention used by the kernel when refering to tokenized LSM labels
 ...
> diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
> index b58adc5..f75a337 100644
> --- a/include/linux/xfrm.h
> +++ b/include/linux/xfrm.h
> @@ -31,7 +31,7 @@ struct xfrm_sec_ctx {
>  	__u8	ctx_doi;
>  	__u8	ctx_alg;
>  	__u16	ctx_len;
> -	__u32	ctx_sid;
> +	__u32	ctx_secid;
>  	char	ctx_str[0];
>  };
>  

This datastructure has been exported to userspace, so we really can't
member names unless it was added only in 2.6.24 and I don't think it
was.

Correct me if I'm wrong.

^ permalink raw reply

* RE: [PATCH] Increase virtual FIFOs in ucc_geth.
From: Joakim Tjernlund @ 2007-12-11 16:55 UTC (permalink / raw)
  To: Li Yang; +Cc: netdev
In-Reply-To: <989B956029373F45A0B8AF029708189001B4D908@zch01exm26.fsl.freescale.net>


On Tue, 2007-12-11 at 19:51 +0800, Li Yang wrote:
> > -----Original Message-----
> > From: Joakim Tjernlund [mailto:joakim.tjernlund@transmode.se] 
> > Sent: Tuesday, December 11, 2007 6:58 PM
> > To: Li Yang
> > Cc: netdev@vger.kernel.org
> > Subject: RE: [PATCH] Increase virtual FIFOs in ucc_geth.
> > 
> > 
> > On Tue, 2007-12-11 at 11:11 +0100, Joakim Tjernlund wrote:
> > > On Tue, 2007-12-11 at 17:49 +0800, Li Yang wrote:
> > > > > -----Original Message-----
> > > > > From: Joakim Tjernlund [mailto:Joakim.Tjernlund@transmode.se] 
> > > > > Sent: Tuesday, December 11, 2007 2:46 AM
> > > > > To: Li Yang-r58472 <LeoLi@freescale.com> Netdev
> > > > > Cc: Joakim Tjernlund
> > > > > Subject: [PATCH] Increase virtual FIFOs in ucc_geth.
> > > > > 
> > > > > Increase UCC_GETH_URFS_INIT to 1152 and
> > > > > UCC_GETH_UTFS_INIT to 896 to avoid HW Overrun/Underrun.
> > > > 
> > > > Please be noted that these values are only used for 
> > 10/100Mbps speed.
> > > > Did you get Overrun in 10/100M mode?
> > > 
> > > I get both TX Underrun and RX overrun in 100Mbps, FD, just
> > > by running a tftp transfer. It feels like the URFET and/or URSFET
> > > isn't working. Why I don't know. CPU is MPC832x
> > > 
> > >   Jocke
> > 
> > I am a bit confused how the RBMR and TBMR is supposed to work. In
> > ucc_get there is:
> >  out_be32(&ugeth->p_tx_glbl_pram->tstate, ((u32) 
> > function_code) << 24);
> >  ugeth->p_rx_glbl_pram->rstate = function_code;
> > First, should not the rx part look the same as tx?
> 
> To be consist with the chip RM, type for tstate is u32 and type for
> rstate is u8.  Personally I don't think that it will be different to
> access tstate as u8, but it will be more readable to be the same as
> manual.  Well, rstate probably should be changed to use IO accessor too.
> 
> > Does programing rstate/tstate replace RBMR and TBMR?
> 
> RBMR and TBMR?  These are for other protocols.
> 
> - Leo

BTW a ping -f -s 90  -l 10 lock the board, can't do
anything useful. NAPI problem?

    Jocke

^ permalink raw reply

* [PATCH 2/2] [IPSEC]: Add ICMP host relookup support
From: Herbert Xu @ 2007-12-11 16:55 UTC (permalink / raw)
  To: David S. Miller, netdev
In-Reply-To: <20071211165317.GA16420@gondor.apana.org.au>

[IPSEC]: Add ICMP host relookup support

RFC 4301 requires us to relookup ICMP traffic that does not match any
policies using the reverse of its payload.  This patch implements this
for ICMP traffic that originates from or terminates on localhost.

This is activated on outbound with the new policy flag XFRM_POLICY_ICMP,
and on inbound by the new state flag XFRM_STATE_ICMP.

On inbound the policy check is now performed by the ICMP protocol so
that it can repeat the policy check where necessary.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/linux/xfrm.h   |    3 +
 include/net/dst.h      |    1 
 net/ipv4/af_inet.c     |    1 
 net/ipv4/icmp.c        |   82 +++++++++++++++++++++++++++++++++++++++++++++++--
 net/ipv6/icmp.c        |   60 +++++++++++++++++++++++++++++++++--
 net/xfrm/xfrm_policy.c |   17 ++++++++--
 6 files changed, 154 insertions(+), 10 deletions(-)

diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index f3819ee..b0c4cc8 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -337,6 +337,7 @@ struct xfrm_usersa_info {
 #define XFRM_STATE_DECAP_DSCP	2
 #define XFRM_STATE_NOPMTUDISC	4
 #define XFRM_STATE_WILDRECV	8
+#define XFRM_STATE_ICMP		16
 };
 
 struct xfrm_usersa_id {
@@ -371,6 +372,8 @@ struct xfrm_userpolicy_info {
 #define XFRM_POLICY_BLOCK	1
 	__u8				flags;
 #define XFRM_POLICY_LOCALOK	1	/* Allow user to override global policy */
+	/* Automatically expand selector to include matching ICMP payloads. */
+#define XFRM_POLICY_ICMP	2
 	__u8				share;
 };
 
diff --git a/include/net/dst.h b/include/net/dst.h
index aaa2dbb..31468c9 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -268,6 +268,7 @@ extern void		dst_init(void);
 /* Flags for xfrm_lookup flags argument. */
 enum {
 	XFRM_LOOKUP_WAIT = 1 << 0,
+	XFRM_LOOKUP_ICMP = 1 << 1,
 };
 
 struct flowi;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 0e4b6eb..48fc0f8 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1291,6 +1291,7 @@ static struct net_protocol udp_protocol = {
 
 static struct net_protocol icmp_protocol = {
 	.handler =	icmp_rcv,
+	.no_policy =	1,
 };
 
 static int __init init_ipv4_mibs(void)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index c0898c5..4e3bfcd 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -92,6 +92,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <net/checksum.h>
+#include <net/xfrm.h>
 
 /*
  *	Build xmit assembly blocks
@@ -564,11 +565,71 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
 				}
 			}
 		};
+		int err;
+		struct rtable *rt2;
+
 		security_skb_classify_flow(skb_in, &fl);
-		if (ip_route_output_key(&rt, &fl))
+		if (__ip_route_output_key(&rt, &fl))
+			goto out_unlock;
+
+		/* No need to clone since we're just using its address. */
+		rt2 = rt;
+
+		err = xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
+		switch (err) {
+		case 0:
+			if (rt != rt2)
+				goto route_done;
+			break;
+		case -EPERM:
+			rt = NULL;
+			break;
+		default:
+			goto out_unlock;
+		}
+
+		if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET))
+			goto out_unlock;
+
+		if (inet_addr_type(fl.fl4_src) == RTN_LOCAL)
+			err = __ip_route_output_key(&rt2, &fl);
+		else {
+			struct flowi fl2 = {};
+			struct dst_entry *odst;
+
+			fl2.fl4_dst = fl.fl4_src;
+			if (ip_route_output_key(&rt2, &fl2))
+				goto out_unlock;
+
+			/* Ugh! */
+			odst = skb_in->dst;
+			err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src,
+					     RT_TOS(tos), rt2->u.dst.dev);
+
+			dst_release(&rt2->u.dst);
+			rt2 = (struct rtable *)skb_in->dst;
+			skb_in->dst = odst;
+		}
+
+		if (err)
+			goto out_unlock;
+
+		err = xfrm_lookup((struct dst_entry **)&rt2, &fl, NULL,
+				  XFRM_LOOKUP_ICMP);
+		if (err == -ENOENT) {
+			if (!rt)
+				goto out_unlock;
+			goto route_done;
+		}
+
+		dst_release(&rt->u.dst);
+		rt = rt2;
+
+		if (err)
 			goto out_unlock;
 	}
 
+route_done:
 	if (!icmpv4_xrlim_allow(rt, type, code))
 		goto ende;
 
@@ -917,6 +978,22 @@ int icmp_rcv(struct sk_buff *skb)
 	struct icmphdr *icmph;
 	struct rtable *rt = (struct rtable *)skb->dst;
 
+	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb) &&
+	    skb->sp->xvec[skb->sp->len - 1]->props.flags & XFRM_STATE_ICMP) {
+		int nh;
+
+		if (!pskb_may_pull(skb, sizeof(*icmph) + sizeof(struct iphdr)))
+			goto drop;
+
+		nh = skb_network_offset(skb);
+		skb_set_network_header(skb, sizeof(*icmph));
+
+		if (!xfrm4_policy_check_reverse(NULL, XFRM_POLICY_IN, skb))
+			goto drop;
+
+		skb_set_network_header(skb, nh);
+	}
+
 	ICMP_INC_STATS_BH(ICMP_MIB_INMSGS);
 
 	switch (skb->ip_summed) {
@@ -930,8 +1007,7 @@ int icmp_rcv(struct sk_buff *skb)
 			goto error;
 	}
 
-	if (!pskb_pull(skb, sizeof(struct icmphdr)))
-		goto error;
+	__skb_pull(skb, sizeof(*icmph));
 
 	icmph = icmp_hdr(skb);
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 4582bbc..478ee77 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -63,6 +63,7 @@
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
 #include <net/icmp.h>
+#include <net/xfrm.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -86,7 +87,7 @@ static int icmpv6_rcv(struct sk_buff *skb);
 
 static struct inet6_protocol icmpv6_protocol = {
 	.handler	=	icmpv6_rcv,
-	.flags		=	INET6_PROTO_FINAL,
+	.flags		=	INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
 
 static __inline__ int icmpv6_xmit_lock(void)
@@ -310,8 +311,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
 	struct ipv6_pinfo *np;
 	struct in6_addr *saddr = NULL;
 	struct dst_entry *dst;
+	struct dst_entry *dst2;
 	struct icmp6hdr tmp_hdr;
 	struct flowi fl;
+	struct flowi fl2;
 	struct icmpv6_msg msg;
 	int iif = 0;
 	int addr_type = 0;
@@ -418,9 +421,42 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
 		goto out_dst_release;
 	}
 
-	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+	/* No need to clone since we're just using its address. */
+	dst2 = dst;
+
+	err = xfrm_lookup(&dst, &fl, sk, 0);
+	switch (err) {
+	case 0:
+		if (dst != dst2)
+			goto route_done;
+		break;
+	case -EPERM:
+		dst = NULL;
+		break;
+	default:
+		goto out;
+	}
+
+	if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6))
+		goto out;
+
+	if (ip6_dst_lookup(sk, &dst2, &fl))
 		goto out;
 
+	err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP);
+	if (err == -ENOENT) {
+		if (!dst)
+			goto out;
+		goto route_done;
+	}
+
+	dst_release(dst);
+	dst = dst2;
+
+	if (err)
+		goto out;
+
+route_done:
 	if (ipv6_addr_is_multicast(&fl.fl6_dst))
 		hlimit = np->mcast_hops;
 	else
@@ -610,6 +646,22 @@ static int icmpv6_rcv(struct sk_buff *skb)
 	struct icmp6hdr *hdr;
 	int type;
 
+	if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb) &&
+	    skb->sp->xvec[skb->sp->len - 1]->props.flags & XFRM_STATE_ICMP) {
+		int nh;
+
+		if (!pskb_may_pull(skb, sizeof(*hdr) + sizeof(*orig_hdr)))
+			goto drop_no_count;
+
+		nh = skb_network_offset(skb);
+		skb_set_network_header(skb, sizeof(*hdr));
+
+		if (!xfrm6_policy_check_reverse(NULL, XFRM_POLICY_IN, skb))
+			goto drop_no_count;
+
+		skb_set_network_header(skb, nh);
+	}
+
 	ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INMSGS);
 
 	saddr = &ipv6_hdr(skb)->saddr;
@@ -632,8 +684,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
 		}
 	}
 
-	if (!pskb_pull(skb, sizeof(struct icmp6hdr)))
-		goto discard_it;
+	__skb_pull(skb, sizeof(*hdr));
 
 	hdr = icmp6_hdr(skb);
 
@@ -719,6 +770,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
 
 discard_it:
 	ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INERRORS);
+drop_no_count:
 	kfree_skb(skb);
 	return 0;
 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 55fd8b7..b04d88c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1469,11 +1469,13 @@ restart:
 			goto dropdst;
 	}
 
+	err = -ENOENT;
+
 	if (!policy) {
 		/* To accelerate a bit...  */
 		if ((dst_orig->flags & DST_NOXFRM) ||
 		    !xfrm_policy_count[XFRM_POLICY_OUT])
-			return 0;
+			goto nopol;
 
 		policy = flow_cache_lookup(fl, dst_orig->ops->family,
 					   dir, xfrm_policy_lookup);
@@ -1483,14 +1485,18 @@ restart:
 	}
 
 	if (!policy)
-		return 0;
+		goto nopol;
 
 	family = dst_orig->ops->family;
-	policy->curlft.use_time = get_seconds();
 	pols[0] = policy;
 	npols ++;
 	xfrm_nr += pols[0]->xfrm_nr;
 
+	if ((flags & XFRM_LOOKUP_ICMP) && !(policy->flags & XFRM_POLICY_ICMP))
+		goto error;
+
+	policy->curlft.use_time = get_seconds();
+
 	switch (policy->action) {
 	default:
 	case XFRM_POLICY_BLOCK:
@@ -1649,6 +1655,11 @@ dropdst:
 	dst_release(dst_orig);
 	*dst_p = NULL;
 	return err;
+
+nopol:
+	if (flags & XFRM_LOOKUP_ICMP)
+		goto dropdst;
+	return 0;
 }
 EXPORT_SYMBOL(__xfrm_lookup);
 

^ permalink raw reply related

* [PATCH 1/2] [IPSEC]: Added xfrm_decode_session_reverse and xfrmX_policy_check_reverse
From: Herbert Xu @ 2007-12-11 16:55 UTC (permalink / raw)
  To: David S. Miller, netdev
In-Reply-To: <20071211165317.GA16420@gondor.apana.org.au>

[IPSEC]: Added xfrm_decode_session_reverse and xfrmX_policy_check_reverse

RFC 4301 requires us to relookup ICMP traffic that does not match any
policies using the reverse of its payload.  This patch adds the functions
xfrm_decode_session_reverse and xfrmX_policy_check_reverse so we can get
the reverse flow to perform such a lookup.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/linux/xfrm.h    |    1 
 include/net/xfrm.h      |   63 ++++++++++++++++++++++++++++++++++++++++++++----
 net/ipv4/xfrm4_policy.c |   10 +++----
 net/ipv6/xfrm6_policy.c |   10 +++----
 net/xfrm/xfrm_policy.c  |   17 ++++++++----
 5 files changed, 80 insertions(+), 21 deletions(-)

diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index df2e62a..f3819ee 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -121,6 +121,7 @@ enum
 	XFRM_POLICY_IN	= 0,
 	XFRM_POLICY_OUT	= 1,
 	XFRM_POLICY_FWD	= 2,
+	XFRM_POLICY_MASK = 3,
 	XFRM_POLICY_MAX	= 3
 };
 
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 92ee8e5..5fae184 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -240,7 +240,8 @@ struct xfrm_policy_afinfo {
 	int			(*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
 	struct dst_entry	*(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
 	void			(*decode_session)(struct sk_buff *skb,
-						  struct flowi *fl);
+						  struct flowi *fl,
+						  int reverse);
 	int			(*get_tos)(struct flowi *fl);
 	int			(*fill_dst)(struct xfrm_dst *xdst,
 					    struct net_device *dev);
@@ -846,14 +847,23 @@ xfrm_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x, unsigned short
 
 extern int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, unsigned short family);
 
-static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
+static inline int __xfrm_policy_check2(struct sock *sk, int dir,
+				       struct sk_buff *skb,
+				       unsigned int family, int reverse)
 {
+	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
+
 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
-		return __xfrm_policy_check(sk, dir, skb, family);
+		return __xfrm_policy_check(sk, ndir, skb, family);
 
 	return	(!xfrm_policy_count[dir] && !skb->sp) ||
 		(skb->dst->flags & DST_NOPOLICY) ||
-		__xfrm_policy_check(sk, dir, skb, family);
+		__xfrm_policy_check(sk, ndir, skb, family);
+}
+
+static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
+{
+	return __xfrm_policy_check2(sk, dir, skb, family, 0);
 }
 
 static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
@@ -866,7 +876,34 @@ static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *s
 	return xfrm_policy_check(sk, dir, skb, AF_INET6);
 }
 
-extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family);
+static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
+					     struct sk_buff *skb)
+{
+	return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
+}
+
+static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
+					     struct sk_buff *skb)
+{
+	return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
+}
+
+extern int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+				 unsigned int family, int reverse);
+
+static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+				      unsigned int family)
+{
+	return __xfrm_decode_session(skb, fl, family, 0);
+}
+
+static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
+					      struct flowi *fl,
+					      unsigned int family)
+{
+	return __xfrm_decode_session(skb, fl, family, 1);
+}
+
 extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
 
 static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
@@ -927,6 +964,22 @@ static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *sk
 {
 	return 1;
 }
+static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
+					      struct flowi *fl,
+					      unsigned int family)
+{
+	return -ENOSYS;
+}
+static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
+					     struct sk_buff *skb)
+{
+	return 1;
+}
+static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
+					     struct sk_buff *skb)
+{
+	return 1;
+}
 #endif
 
 static __inline__
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 10b72d1..5ccae3a 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -115,7 +115,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
 }
 
 static void
-_decode_session4(struct sk_buff *skb, struct flowi *fl)
+_decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
 {
 	struct iphdr *iph = ip_hdr(skb);
 	u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
@@ -131,8 +131,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
 			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
 				__be16 *ports = (__be16 *)xprth;
 
-				fl->fl_ip_sport = ports[0];
-				fl->fl_ip_dport = ports[1];
+				fl->fl_ip_sport = ports[!!reverse];
+				fl->fl_ip_dport = ports[!reverse];
 			}
 			break;
 
@@ -174,8 +174,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
 		}
 	}
 	fl->proto = iph->protocol;
-	fl->fl4_dst = iph->daddr;
-	fl->fl4_src = iph->saddr;
+	fl->fl4_dst = reverse ? iph->saddr : iph->daddr;
+	fl->fl4_src = reverse ? iph->daddr : iph->saddr;
 	fl->fl4_tos = iph->tos;
 }
 
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 9c14e02..6714831 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -124,7 +124,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
 }
 
 static inline void
-_decode_session6(struct sk_buff *skb, struct flowi *fl)
+_decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
 {
 	u16 offset = skb_network_header_len(skb);
 	struct ipv6hdr *hdr = ipv6_hdr(skb);
@@ -133,8 +133,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
 	u8 nexthdr = nh[IP6CB(skb)->nhoff];
 
 	memset(fl, 0, sizeof(struct flowi));
-	ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr);
-	ipv6_addr_copy(&fl->fl6_src, &hdr->saddr);
+	ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr);
+	ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr);
 
 	while (pskb_may_pull(skb, nh + offset + 1 - skb->data)) {
 		nh = skb_network_header(skb);
@@ -157,8 +157,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
 			if (pskb_may_pull(skb, nh + offset + 4 - skb->data)) {
 				__be16 *ports = (__be16 *)exthdr;
 
-				fl->fl_ip_sport = ports[0];
-				fl->fl_ip_dport = ports[1];
+				fl->fl_ip_sport = ports[!!reverse];
+				fl->fl_ip_dport = ports[!reverse];
 			}
 			fl->proto = nexthdr;
 			return;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 265c679..55fd8b7 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1732,8 +1732,8 @@ xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start,
 	return start;
 }
 
-int
-xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family)
+int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+			  unsigned int family, int reverse)
 {
 	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
 	int err;
@@ -1741,12 +1741,12 @@ xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family
 	if (unlikely(afinfo == NULL))
 		return -EAFNOSUPPORT;
 
-	afinfo->decode_session(skb, fl);
+	afinfo->decode_session(skb, fl, reverse);
 	err = security_xfrm_decode_session(skb, &fl->secid);
 	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }
-EXPORT_SYMBOL(xfrm_decode_session);
+EXPORT_SYMBOL(__xfrm_decode_session);
 
 static inline int secpath_has_nontransport(struct sec_path *sp, int k, int *idxp)
 {
@@ -1768,11 +1768,16 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 	int npols = 0;
 	int xfrm_nr;
 	int pi;
+	int reverse;
 	struct flowi fl;
-	u8 fl_dir = policy_to_flow_dir(dir);
+	u8 fl_dir;
 	int xerr_idx = -1;
 
-	if (xfrm_decode_session(skb, &fl, family) < 0)
+	reverse = dir & ~XFRM_POLICY_MASK;
+	dir &= XFRM_POLICY_MASK;
+	fl_dir = policy_to_flow_dir(dir);
+
+	if (__xfrm_decode_session(skb, &fl, family, reverse) < 0)
 		return 0;
 	nf_nat_decode_session(skb, &fl, family);
 

^ permalink raw reply related

* [0/2] [IPSEC]: Add host ICMP relookup support
From: Herbert Xu @ 2007-12-11 16:53 UTC (permalink / raw)
  To: David S. Miller, netdev

Hi Dave:

These two patches implement the ICMP relookup feature for hosts
that's required by RFC 4301.  I've made it conditional on policy
and state flags so it should have no impact on existing users.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH] IPv6 support for NFS server
From: Aurélien Charbon @ 2007-12-11 16:46 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: netdev ML, Mailing list NFSv4
In-Reply-To: <20071210183414.GB28557@fieldses.org>

J. Bruce Fields wrote:

>On Mon, Dec 10, 2007 at 07:34:41PM +0100, Aurélien Charbon wrote:
>  
>
>>Here is a cleanup for the ip_map caching patch in nfs server.
>>
>>It prepares for IPv6 text-based mounts and exports.
>>
>>Tests: tested with only IPv4 network and basic nfs ops (mount, file 
>>creation and modification)
>>    
>>
>
>Thanks!  And also tested with an unmodified rpc.mountd?
>  
>
Yes I also tested it with a basic nfs-utils-1.1.1 + CITI NFS4_ALL-1 patch.

Aurélien

-- 

********************************
       Aurelien Charbon
       Linux NFSv4 team
           Bull SAS
     Echirolles - France
http://nfsv4.bullopensource.org/
********************************

_______________________________________________
NFSv4 mailing list
NFSv4@linux-nfs.org
http://linux-nfs.org/cgi-bin/mailman/listinfo/nfsv4

^ permalink raw reply

* Re: [PATCH] IPv6 support for NFS server
From: Brian Haley @ 2007-12-11 16:41 UTC (permalink / raw)
  To: Aurélien Charbon; +Cc: Mailing list NFSv4, netdev ML
In-Reply-To: <475D86C1.6070400@ext.bull.net>

Hi Aurelien,

Aurélien Charbon wrote:
> 
> Here is a cleanup for the ip_map caching patch in nfs server.
> 
> It prepares for IPv6 text-based mounts and exports.
> 
> Tests: tested with only IPv4 network and basic nfs ops (mount, file 
> creation and modification)

In an email back on October 29th I sent-out a similar patch with a new 
ipv6_addr_set_v4mapped() inline - it might be useful to pull that piece 
into your patch since it cleans it up a bit to get rid of the 
ipv6_addr_set() calls.  I can re-send you that patch off-line if you 
can't find it.

-Brian

^ permalink raw reply

* [PATCH v2] XFRM: assorted IPsec fixups
From: Paul Moore @ 2007-12-11 16:30 UTC (permalink / raw)
  To: netdev; +Cc: linux-audit, selinux

This patch fixes a number of small but potentially troublesome things in the
XFRM/IPsec code:

 * Use the 'audit_enabled' variable already in include/linux/audit.h
   Removed the need for extern declarations local to each XFRM audit fuction

 * Convert 'sid' to 'secid'
   The 'sid' name is specific to SELinux, 'secid' is the common naming
   convention used by the kernel when refering to tokenized LSM labels

 * Convert address display to use standard NIP* macros
   Similar to what was recently done with the SPD audit code, this also also
   includes the removal of some unnecessary memcpy() calls

 * Move common code to xfrm_audit_common_stateinfo()
   Code consolidation from the "less is more" book on software development

 * Convert the SPI in audit records to host byte order
   The current SPI values in the audit record are being displayed in network
   byte order, probably not what was intended

 * Proper spacing around commas in function arguments
   Minor style tweak since I was already touching the code

Signed-off-by: Paul Moore <paul.moore@hp.com>
---

 include/linux/xfrm.h    |    2 +
 include/net/xfrm.h      |   18 ++++++------
 net/xfrm/xfrm_policy.c  |   15 +++++-----
 net/xfrm/xfrm_state.c   |   69 +++++++++++++++++++++--------------------------
 security/selinux/xfrm.c |   20 +++++++-------
 5 files changed, 58 insertions(+), 66 deletions(-)

diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index b58adc5..f75a337 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -31,7 +31,7 @@ struct xfrm_sec_ctx {
 	__u8	ctx_doi;
 	__u8	ctx_alg;
 	__u16	ctx_len;
-	__u32	ctx_sid;
+	__u32	ctx_secid;
 	char	ctx_str[0];
 };
 
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0c380d9..3134ba6 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -547,7 +547,7 @@ struct xfrm_audit
 };
 
 #ifdef CONFIG_AUDITSYSCALL
-static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
+static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 secid)
 {
 	struct audit_buffer *audit_buf = NULL;
 	char *secctx;
@@ -560,8 +560,8 @@ static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
 
 	audit_log_format(audit_buf, "auid=%u", auid);
 
-	if (sid != 0 &&
-	    security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) {
+	if (secid != 0 &&
+	    security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) {
 		audit_log_format(audit_buf, " subj=%s", secctx);
 		security_release_secctx(secctx, secctx_len);
 	} else
@@ -570,13 +570,13 @@ static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
 }
 
 extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
-				  u32 auid, u32 sid);
+				  u32 auid, u32 secid);
 extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
-				  u32 auid, u32 sid);
+				  u32 auid, u32 secid);
 extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
-				 u32 auid, u32 sid);
+				 u32 auid, u32 secid);
 extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
-				    u32 auid, u32 sid);
+				    u32 auid, u32 secid);
 #else
 #define xfrm_audit_policy_add(x, r, a, s)	do { ; } while (0)
 #define xfrm_audit_policy_delete(x, r, a, s)	do { ; } while (0)
@@ -706,13 +706,13 @@ extern int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 /*	If neither has a context --> match
- * 	Otherwise, both must have a context and the sids, doi, alg must match
+ * 	Otherwise, both must have a context and the secids, doi, alg must match
  */
 static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
 {
 	return ((!s1 && !s2) ||
 		(s1 && s2 &&
-		 (s1->ctx_sid == s2->ctx_sid) &&
+		 (s1->ctx_secid == s2->ctx_secid) &&
 		 (s1->ctx_doi == s2->ctx_doi) &&
 		 (s1->ctx_alg == s2->ctx_alg)));
 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d9bde91..8a89e2c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -24,6 +24,7 @@
 #include <linux/netfilter.h>
 #include <linux/module.h>
 #include <linux/cache.h>
+#include <linux/audit.h>
 #include <net/dst.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
@@ -2298,15 +2299,14 @@ static inline void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
 	}
 }
 
-void
-xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
+void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
+			   u32 auid, u32 secid)
 {
 	struct audit_buffer *audit_buf;
-	extern int audit_enabled;
 
 	if (audit_enabled == 0)
 		return;
-	audit_buf = xfrm_audit_start(sid, auid);
+	audit_buf = xfrm_audit_start(secid, auid);
 	if (audit_buf == NULL)
 		return;
 	audit_log_format(audit_buf, " op=SPD-add res=%u", result);
@@ -2315,15 +2315,14 @@ xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
 }
 EXPORT_SYMBOL_GPL(xfrm_audit_policy_add);
 
-void
-xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
+void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
+			      u32 auid, u32 secid)
 {
 	struct audit_buffer *audit_buf;
-	extern int audit_enabled;
 
 	if (audit_enabled == 0)
 		return;
-	audit_buf = xfrm_audit_start(sid, auid);
+	audit_buf = xfrm_audit_start(secid, auid);
 	if (audit_buf == NULL)
 		return;
 	audit_log_format(audit_buf, " op=SPD-delete res=%u", result);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 5b860b6..e2a3dd1 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -19,6 +19,7 @@
 #include <linux/ipsec.h>
 #include <linux/module.h>
 #include <linux/cache.h>
+#include <linux/audit.h>
 #include <asm/uaccess.h>
 
 #include "xfrm_hash.h"
@@ -1994,67 +1995,59 @@ void __init xfrm_state_init(void)
 static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x,
 					       struct audit_buffer *audit_buf)
 {
-	if (x->security)
-		audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
-				 x->security->ctx_alg, x->security->ctx_doi,
-				 x->security->ctx_str);
+	struct xfrm_sec_ctx *ctx = x->security;
+	u32 spi = ntohl(x->id.spi);
 
-	switch(x->props.family) {
-	case AF_INET:
-		audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
-				 NIPQUAD(x->props.saddr.a4),
-				 NIPQUAD(x->id.daddr.a4));
-		break;
-	case AF_INET6:
-		{
-			struct in6_addr saddr6, daddr6;
-
-			memcpy(&saddr6, x->props.saddr.a6,
-				sizeof(struct in6_addr));
-			memcpy(&daddr6, x->id.daddr.a6,
-				sizeof(struct in6_addr));
-			audit_log_format(audit_buf,
-					 " src=" NIP6_FMT " dst=" NIP6_FMT,
-					 NIP6(saddr6), NIP6(daddr6));
-		}
-		break;
-	}
+        if (ctx)
+                audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
+                                 ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
+
+        switch(x->props.family) {
+        case AF_INET:
+                audit_log_format(audit_buf,
+				 " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
+                                 NIPQUAD(x->props.saddr.a4),
+                                 NIPQUAD(x->id.daddr.a4));
+                break;
+        case AF_INET6:
+		audit_log_format(audit_buf,
+				 " src=" NIP6_FMT " dst=" NIP6_FMT,
+				 NIP6(*(struct in6_addr *)x->props.saddr.a6),
+				 NIP6(*(struct in6_addr *)x->id.daddr.a6));
+                break;
+        }
+
+	audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
 }
 
-void
-xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid)
+void xfrm_audit_state_add(struct xfrm_state *x, int result,
+			  u32 auid, u32 secid)
 {
 	struct audit_buffer *audit_buf;
-	extern int audit_enabled;
 
 	if (audit_enabled == 0)
 		return;
-	audit_buf = xfrm_audit_start(sid, auid);
+	audit_buf = xfrm_audit_start(secid, auid);
 	if (audit_buf == NULL)
 		return;
-	audit_log_format(audit_buf, " op=SAD-add res=%u",result);
+	audit_log_format(audit_buf, " op=SAD-add res=%u", result);
 	xfrm_audit_common_stateinfo(x, audit_buf);
-	audit_log_format(audit_buf, " spi=%lu(0x%lx)",
-			 (unsigned long)x->id.spi, (unsigned long)x->id.spi);
 	audit_log_end(audit_buf);
 }
 EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
 
-void
-xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid)
+void xfrm_audit_state_delete(struct xfrm_state *x, int result,
+			     u32 auid, u32 secid)
 {
 	struct audit_buffer *audit_buf;
-	extern int audit_enabled;
 
 	if (audit_enabled == 0)
 		return;
-	audit_buf = xfrm_audit_start(sid, auid);
+	audit_buf = xfrm_audit_start(secid, auid);
 	if (audit_buf == NULL)
 		return;
-	audit_log_format(audit_buf, " op=SAD-delete res=%u",result);
+	audit_log_format(audit_buf, " op=SAD-delete res=%u", result);
 	xfrm_audit_common_stateinfo(x, audit_buf);
-	audit_log_format(audit_buf, " spi=%lu(0x%lx)",
-			 (unsigned long)x->id.spi, (unsigned long)x->id.spi);
 	audit_log_end(audit_buf);
 }
 EXPORT_SYMBOL_GPL(xfrm_audit_state_delete);
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index e076039..c925880 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -85,7 +85,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
 		if (!selinux_authorizable_ctx(ctx))
 			return -EINVAL;
 
-		sel_sid = ctx->ctx_sid;
+		sel_sid = ctx->ctx_secid;
 	}
 	else
 		/*
@@ -132,7 +132,7 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
 				/* Not a SELinux-labeled SA */
 				return 0;
 
-	state_sid = x->security->ctx_sid;
+	state_sid = x->security->ctx_secid;
 
 	if (fl->secid != state_sid)
 		return 0;
@@ -175,13 +175,13 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
 				struct xfrm_sec_ctx *ctx = x->security;
 
 				if (!sid_set) {
-					*sid = ctx->ctx_sid;
+					*sid = ctx->ctx_secid;
 					sid_set = 1;
 
 					if (!ckall)
 						break;
 				}
-				else if (*sid != ctx->ctx_sid)
+				else if (*sid != ctx->ctx_secid)
 					return -EINVAL;
 			}
 		}
@@ -232,7 +232,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
 	ctx->ctx_str[str_len] = 0;
 	rc = security_context_to_sid(ctx->ctx_str,
 				     str_len,
-				     &ctx->ctx_sid);
+				     &ctx->ctx_secid);
 
 	if (rc)
 		goto out;
@@ -240,7 +240,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
 	/*
 	 * Does the subject have permission to set security context?
 	 */
-	rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+	rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
 			  SECCLASS_ASSOCIATION,
 			  ASSOCIATION__SETCONTEXT, NULL);
 	if (rc)
@@ -264,7 +264,7 @@ not_from_user:
 
 	ctx->ctx_doi = XFRM_SC_DOI_LSM;
 	ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
-	ctx->ctx_sid = sid;
+	ctx->ctx_secid = sid;
 	ctx->ctx_len = str_len;
 	memcpy(ctx->ctx_str,
 	       ctx_str,
@@ -341,7 +341,7 @@ int selinux_xfrm_policy_delete(struct xfrm_policy *xp)
 	int rc = 0;
 
 	if (ctx)
-		rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+		rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
 				  SECCLASS_ASSOCIATION,
 				  ASSOCIATION__SETCONTEXT, NULL);
 
@@ -383,7 +383,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
 	int rc = 0;
 
 	if (ctx)
-		rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+		rc = avc_has_perm(tsec->sid, ctx->ctx_secid,
 				  SECCLASS_ASSOCIATION,
 				  ASSOCIATION__SETCONTEXT, NULL);
 
@@ -412,7 +412,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
 
 			if (x && selinux_authorizable_xfrm(x)) {
 				struct xfrm_sec_ctx *ctx = x->security;
-				sel_sid = ctx->ctx_sid;
+				sel_sid = ctx->ctx_secid;
 				break;
 			}
 		}

^ permalink raw reply related

* Re: [kvm-devel] [PATCH resent] virtio_net: Fix stalled inbound trafficon early packets
From: Christian Borntraeger @ 2007-12-11 15:27 UTC (permalink / raw)
  To: dor.laor; +Cc: Rusty Russell, kvm-devel, netdev, virtualization
In-Reply-To: <200712111419.52880.borntraeger@de.ibm.com>

Am Dienstag, 11. Dezember 2007 schrieb Christian Borntraeger:
> > The way other physical NICs doing it is by dis/en/abling interrupt 
> > using registers (look at e1000).
> > I suggest we can export add_status and use the original code but
> > before enabling napi add a call to add_status(dev, 
> > VIRTIO_CONFIG_DEV_OPEN).
> > The host won't trigger an irq until it sees the above.
> 
> That would also work. We already have VRING_AVAIL_F_NO_INTERRUPT in
> virtio_ring.c - maybe we can use that. Its hidden in callback and
> restart handling, what about adding an explicit startup?

Ok, just to give an example what I thought about:
---
 drivers/block/virtio_blk.c   |    3 ++-
 drivers/net/virtio_net.c     |    2 ++
 drivers/virtio/virtio_ring.c |   16 +++++++++++++---
 include/linux/virtio.h       |    5 +++++
 4 files changed, 22 insertions(+), 4 deletions(-)

Index: kvm/drivers/virtio/virtio_ring.c
===================================================================
--- kvm.orig/drivers/virtio/virtio_ring.c
+++ kvm/drivers/virtio/virtio_ring.c
@@ -241,6 +241,16 @@ static bool vring_restart(struct virtque
 	return true;
 }
 
+static void vring_startup(struct virtqueue *_vq)
+{
+	struct vring_virtqueue *vq = to_vvq(_vq);
+	START_USE(vq);
+	if (vq->vq.callback)
+		vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
+	END_USE(vq);
+}
+
+
 irqreturn_t vring_interrupt(int irq, void *_vq)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
@@ -265,6 +275,7 @@ static struct virtqueue_ops vring_vq_ops
 	.get_buf = vring_get_buf,
 	.kick = vring_kick,
 	.restart = vring_restart,
+	.startup = vring_startup,
 	.shutdown = vring_shutdown,
 };
 
@@ -299,9 +310,8 @@ struct virtqueue *vring_new_virtqueue(un
 	vq->in_use = false;
 #endif
 
-	/* No callback?  Tell other side not to bother us. */
-	if (!callback)
-		vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+	/* disable interrupts until we enable them */
+	vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
 
 	/* Put everything in free lists. */
 	vq->num_free = num;
Index: kvm/include/linux/virtio.h
===================================================================
--- kvm.orig/include/linux/virtio.h
+++ kvm/include/linux/virtio.h
@@ -45,6 +45,9 @@ struct virtqueue
  *	vq: the struct virtqueue we're talking about.
  *	This returns "false" (and doesn't re-enable) if there are pending
  *	buffers in the queue, to avoid a race.
+ * @startup: enable callbacks
+ *	vq: the struct virtqueue we're talking abount
+ *	Returns 0 or an error
  * @shutdown: "unadd" all buffers.
  *	vq: the struct virtqueue we're talking about.
  *	Remove everything from the queue.
@@ -67,6 +70,8 @@ struct virtqueue_ops {
 
 	bool (*restart)(struct virtqueue *vq);
 
+	void (*startup) (struct virtqueue *vq);
+
 	void (*shutdown)(struct virtqueue *vq);
 };
 
Index: kvm/drivers/net/virtio_net.c
===================================================================
--- kvm.orig/drivers/net/virtio_net.c
+++ kvm/drivers/net/virtio_net.c
@@ -292,6 +292,8 @@ static int virtnet_open(struct net_devic
 		return -ENOMEM;
 
 	napi_enable(&vi->napi);
+
+	vi->rvq->vq_ops->startup(vi->rvq);
 	return 0;
 }
 
Index: kvm/drivers/block/virtio_blk.c
===================================================================
--- kvm.orig/drivers/block/virtio_blk.c
+++ kvm/drivers/block/virtio_blk.c
@@ -183,7 +183,8 @@ static int virtblk_probe(struct virtio_d
 		err = PTR_ERR(vblk->vq);
 		goto out_free_vblk;
 	}
-
+	/* enable interrupts */
+	vblk->vq->vq_ops->startup(vblk->vq);
 	vblk->pool = mempool_create_kmalloc_pool(1,sizeof(struct virtblk_req));
 	if (!vblk->pool) {
 		err = -ENOMEM;



There is still one small problem: what if the host fills up all 
host-to-guest buffers before we call startup? So I start to think that your 
solution is better, given that the host is not only not sending interrupts 
but also not filling any buffers as long as VIRTIO_CONFIG_DEV_OPEN is not 
set. I will have a look but I think that add_status needs to be called 
after napi_enable, otherwise we have the same race.

Christian

^ permalink raw reply

* [PATCH]drivers/net/phy/: default return value in ioctl phy.c
From: Rini van Zetten @ 2007-12-11 15:02 UTC (permalink / raw)
  To: afleming; +Cc: netdev, linux-kernel

Hello Andy,

This patch (to 2.6.23.9) add a default return value EOPNOTSUPP to the ioctl 
function. The problem with the always 0 return value is that the iwconfig 
(wireless) tool found a valid device when an ethernet device uses the phy 
abstraction layer.
I 've tetsted this with the macb driver.


Signed-off-by: Rini van Zetten <rini@arvoo.nl>

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index cb230f4..c07460d 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -405,6 +405,8 @@ int phy_mii_ioctl(struct phy_device *phydev,
                                && phydev->drv->config_init)
                        phydev->drv->config_init(phydev);
                break;
+       default:
+               return -EOPNOTSUPP;
        }

        return 0;


^ permalink raw reply related

* Re: [PATCH 2/2] [TCP]: Include __tcp_reset_fack_counts to non-__ version
From: Christoph Hellwig @ 2007-12-11 15:13 UTC (permalink / raw)
  To: Ilpo J?rvinen; +Cc: David Miller, netdev
In-Reply-To: <11973738392955-git-send-email-ilpo.jarvinen@helsinki.fi>

On Tue, Dec 11, 2007 at 01:50:39PM +0200, Ilpo J?rvinen wrote:
> +		BUG_ON((prev != NULL) && !tcp_skb_adjacent(sk, prev, skb[queue]));
> +
> +		tcp_for_write_queue_from(skb[queue], sk, queue) {
> +			if ((prev != NULL) && !tcp_skb_adjacent(sk, prev, skb[queue]))
> +				break;
> +
> +			if (!before(TCP_SKB_CB(skb[queue])->seq, tcp_sk(sk)->snd_nxt) ||
> +			    TCP_SKB_CB(skb[queue])->fack_count == fc)
> +				return;

There's quite a few overflows of the normal 80 char limit here.  Because
you're current style is a little on the verbose side that's trivially
fixable, though:

		BUG_ON(prev && !tcp_skb_adjacent(sk, prev, skb[queue]));

		tcp_for_write_queue_from(skb[queue], sk, queue) {
			if (prev && !tcp_skb_adjacent(sk, prev, skb[queue]))
				break;

			if (!before(TCP_SKB_CB(skb[queue])->seq,
					       tcp_sk(sk)->snd_nxt) ||
			    TCP_SKB_CB(skb[queue])->fack_count == fc)
				return;


^ permalink raw reply

* Re: [Bugme-new] [Bug 9543] New: RTNL: assertion failed at net/ipv6/addrconf.c (2164)/RTNL: assertion failed at net/ipv4/devinet.c (1055)
From: Krzysztof Oledzki @ 2007-12-11 15:04 UTC (permalink / raw)
  To: Andrew Morton; +Cc: bugme-daemon, Stephen Hemminger, David S. Miller, netdev
In-Reply-To: <20071211034603.cbcc4762.akpm@linux-foundation.org>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2265 bytes --]



On Tue, 11 Dec 2007, Andrew Morton wrote:

> On Tue, 11 Dec 2007 03:20:48 -0800 (PST) bugme-daemon@bugzilla.kernel.org wrote:
>
>> http://bugzilla.kernel.org/show_bug.cgi?id=9543
>>
>>            Summary: RTNL: assertion failed at net/ipv6/addrconf.c
>>                     (2164)/RTNL: assertion failed at net/ipv4/devinet.c
>>                     (1055)
>>            Product: Drivers
>>            Version: 2.5
>>      KernelVersion: 2.6.24-rc4-git7
>>           Platform: All
>>         OS/Version: Linux
>>               Tree: Mainline
>>             Status: NEW
>>           Severity: normal
>>           Priority: P1
>>          Component: Network
>>         AssignedTo: jgarzik@pobox.com
>>         ReportedBy: olel@ans.pl
>>
>>
>> Most recent kernel where this bug did not occur: 2.6.23
>> Distribution: Gentoo
>>
>> Problem Description:
>> ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready
>> RTNL: assertion failed at net/ipv6/addrconf.c (2164)
>> Pid: 9, comm: events/0 Not tainted 2.6.24-rc4-git7 #1
>>  [<78402cfb>] addrconf_notify+0x5b4/0x7b7
>>  [<7812203a>] finish_task_switch+0x0/0x8c
>>  [<781346ff>] worker_thread+0x0/0x85
>>  [<78438e23>] schedule+0x545/0x55f
>>  [<781408d1>] print_lock_contention_bug+0x11/0xd2
>>  [<783bfa72>] rt_run_flush+0x43/0x8b
>>  [<783bfa93>] rt_run_flush+0x64/0x8b
>>  [<7813ac54>] notifier_call_chain+0x2a/0x52
>>  [<7813ac9e>] raw_notifier_call_chain+0x17/0x1a
>>  [<783a3471>] netdev_state_change+0x18/0x29
>>  [<783ac6a9>] __linkwatch_run_queue+0x150/0x17e
>>  [<783ac6f4>] linkwatch_event+0x1d/0x22
>>  [<78133cdf>] run_workqueue+0xdb/0x1b6
>>  [<78133c8b>] run_workqueue+0x87/0x1b6
>>  [<783ac6d7>] linkwatch_event+0x0/0x22
>>  [<781346ff>] worker_thread+0x0/0x85
>>  [<78134778>] worker_thread+0x79/0x85
>>  [<781371ad>] autoremove_wake_function+0x0/0x35
>>  [<781370f6>] kthread+0x38/0x5e
>>  [<781370be>] kthread+0x0/0x5e
>>  [<78104baf>] kernel_thread_helper+0x7/0x10
>>  =======================
>> RTNL: assertion failed at net/ipv6/addrconf.c (1610)
>
>
> Hopefully this is due to the bug you reported in bug #9542.
>
> Does this patch fix both issues?

Unfortunately not. I just updated bugzilla.

Best regards,

 				Krzysztof Olędzki

^ permalink raw reply

* [PATCH 2/2] add driver for enc28j60 ethernet chip
From: Claudio Lanconelli @ 2007-12-11 14:58 UTC (permalink / raw)
  To: netdev; +Cc: jgarzik

[-- Attachment #1: Type: text/plain, Size: 138 bytes --]

Second part contains changes on Kconfig and Makefile on dir drivers/net

Signed-off-by: Claudio Lanconelli <lanconelli.claudio@eptar.com>

[-- Attachment #2: enc28j60_p2.diff --]
[-- Type: text/x-patch, Size: 1605 bytes --]

 drivers/net/Kconfig  |   26 ++++++++++++++++++++++++++
 drivers/net/Makefile |    1 +
 2 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index d9107e5..e643e0f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -922,6 +922,32 @@ config DM9000
 	  To compile this driver as a module, choose M here.  The module
 	  will be called dm9000.
 
+config ENC28J60
+	tristate "ENC28J60 support"
+	depends on EXPERIMENTAL && SPI && NET_ETHERNET
+	select CRC32
+	select MII
+	---help---
+	  Support for the Microchip EN28J60 ethernet chip.
+
+	  To compile this driver as a module, choose M here and read
+	  <file:Documentation/networking/net-modules.txt>.  The module will be
+	  called enc28j60.
+
+config ENC28J60_DBGLEVEL
+	int "Debugging verbosity (0 = quiet, 3 = noisy)"
+	depends on ENC28J60
+	default "0"
+	---help---
+	  Determines the verbosity level of the enc28j60 driver debugging messages.
+
+config ENC28J60_WRITEVERIFY
+	bool "Enable write verify"
+	depends on ENC28J60
+	---help---
+	  Enable the verify after the buffer write useful for debugging purpose.
+	  If unsure, say N.
+
 config SMC911X
 	tristate "SMSC LAN911[5678] support"
 	select CRC32
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 0e5fde4..e91e3a3 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -216,6 +216,7 @@ obj-$(CONFIG_DM9000) += dm9000.o
 obj-$(CONFIG_FEC_8XX) += fec_8xx/
 obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
 obj-$(CONFIG_MLX4_CORE) += mlx4/
+obj-$(CONFIG_ENC28J60) += enc28j60.o
 
 obj-$(CONFIG_MACB) += macb.o
 



^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox