Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorDavid S. Miller <davem@davemloft.net>
Fri, 15 Jun 2012 22:51:55 +0000 (15:51 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Jun 2012 22:51:55 +0000 (15:51 -0700)
Conflicts:
net/ipv6/route.c

This deals with a merge conflict between the net-next addition of the
inetpeer network namespace ops, and Thomas Graf's bug fix in
2a0c451ade8e1783c5d453948289e4a978d417c9 which makes sure we don't
register /proc/net/ipv6_route before it is actually safe to do so.

Signed-off-by: David S. Miller <davem@davemloft.net>
1  2 
MAINTAINERS
drivers/net/can/c_can/c_can.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
include/net/ip6_fib.h
net/core/dev.c
net/ipv6/ip6_fib.c
net/ipv6/route.c

diff --combined MAINTAINERS
@@@ -329,7 -329,7 +329,7 @@@ F: drivers/hwmon/adm1029.
  
  ADM8211 WIRELESS DRIVER
  L:    linux-wireless@vger.kernel.org
 -W:    http://linuxwireless.org/
 +W:    http://wireless.kernel.org/
  S:    Orphan
  F:    drivers/net/wireless/adm8211.*
  
@@@ -1077,7 -1077,7 +1077,7 @@@ F:      drivers/media/video/s5p-fimc
  ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
  M:    Kyungmin Park <kyungmin.park@samsung.com>
  M:    Kamil Debski <k.debski@samsung.com>
- M:     Jeongtae Park <jtp.park@samsung.com>
+ M:    Jeongtae Park <jtp.park@samsung.com>
  L:    linux-arm-kernel@lists.infradead.org
  L:    linux-media@vger.kernel.org
  S:    Maintained
@@@ -1423,7 -1423,7 +1423,7 @@@ B43 WIRELESS DRIVE
  M:    Stefano Brivio <stefano.brivio@polimi.it>
  L:    linux-wireless@vger.kernel.org
  L:    b43-dev@lists.infradead.org
 -W:    http://linuxwireless.org/en/users/Drivers/b43
 +W:    http://wireless.kernel.org/en/users/Drivers/b43
  S:    Maintained
  F:    drivers/net/wireless/b43/
  
@@@ -1432,7 -1432,7 +1432,7 @@@ M:      Larry Finger <Larry.Finger@lwfinger.
  M:    Stefano Brivio <stefano.brivio@polimi.it>
  L:    linux-wireless@vger.kernel.org
  L:    b43-dev@lists.infradead.org
 -W:    http://linuxwireless.org/en/users/Drivers/b43
 +W:    http://wireless.kernel.org/en/users/Drivers/b43
  S:    Maintained
  F:    drivers/net/wireless/b43legacy/
  
@@@ -1743,10 -1743,10 +1743,10 @@@ F:   include/linux/can/platform
  CAPABILITIES
  M:    Serge Hallyn <serge.hallyn@canonical.com>
  L:    linux-security-module@vger.kernel.org
- S:    Supported       
+ S:    Supported
  F:    include/linux/capability.h
  F:    security/capability.c
- F:    security/commoncap.c 
+ F:    security/commoncap.c
  F:    kernel/capability.c
  
  CELL BROADBAND ENGINE ARCHITECTURE
@@@ -2149,11 -2149,11 +2149,11 @@@ S:   Orpha
  F:    drivers/net/wan/pc300*
  
  CYTTSP TOUCHSCREEN DRIVER
- M:      Javier Martinez Canillas <javier@dowhile0.org>
- L:      linux-input@vger.kernel.org
- S:      Maintained
- F:      drivers/input/touchscreen/cyttsp*
- F:      include/linux/input/cyttsp.h
+ M:    Javier Martinez Canillas <javier@dowhile0.org>
+ L:    linux-input@vger.kernel.org
+ S:    Maintained
+ F:    drivers/input/touchscreen/cyttsp*
+ F:    include/linux/input/cyttsp.h
  
  DAMA SLAVE for AX.25
  M:    Joerg Reuter <jreuter@yaina.de>
@@@ -2273,7 -2273,7 +2273,7 @@@ F:      include/linux/device-mapper.
  F:    include/linux/dm-*.h
  
  DIOLAN U2C-12 I2C DRIVER
- M:    Guenter Roeck <guenter.roeck@ericsson.com>
+ M:    Guenter Roeck <linux@roeck-us.net>
  L:    linux-i2c@vger.kernel.org
  S:    Maintained
  F:    drivers/i2c/busses/i2c-diolan-u2c.c
@@@ -2933,6 -2933,13 +2933,13 @@@ F:    Documentation/power/freezing-of-task
  F:    include/linux/freezer.h
  F:    kernel/freezer.c
  
+ FRONTSWAP API
+ M:    Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+ L:    linux-kernel@vger.kernel.org
+ S:    Maintained
+ F:    mm/frontswap.c
+ F:    include/linux/frontswap.h
  FS-CACHE: LOCAL CACHING FOR NETWORK FILESYSTEMS
  M:    David Howells <dhowells@redhat.com>
  L:    linux-cachefs@redhat.com
@@@ -3141,7 -3148,7 +3148,7 @@@ F:      drivers/tty/hvc
  
  HARDWARE MONITORING
  M:    Jean Delvare <khali@linux-fr.org>
- M:    Guenter Roeck <guenter.roeck@ericsson.com>
+ M:    Guenter Roeck <linux@roeck-us.net>
  L:    lm-sensors@lm-sensors.org
  W:    http://www.lm-sensors.org/
  T:    quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/
@@@ -4099,6 -4106,8 +4106,8 @@@ F:      drivers/scsi/53c700
  LED SUBSYSTEM
  M:    Bryan Wu <bryan.wu@canonical.com>
  M:    Richard Purdie <rpurdie@rpsys.net>
+ L:    linux-leds@vger.kernel.org
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds.git
  S:    Maintained
  F:    drivers/leds/
  F:    include/linux/leds.h
@@@ -4342,7 -4351,7 +4351,7 @@@ F:      arch/m68k/hp300
  MAC80211
  M:    Johannes Berg <johannes@sipsolutions.net>
  L:    linux-wireless@vger.kernel.org
 -W:    http://linuxwireless.org/
 +W:    http://wireless.kernel.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
  S:    Maintained
@@@ -4354,7 -4363,7 +4363,7 @@@ MAC80211 PID RATE CONTRO
  M:    Stefano Brivio <stefano.brivio@polimi.it>
  M:    Mattias Nissler <mattias.nissler@gmx.de>
  L:    linux-wireless@vger.kernel.org
 -W:    http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID
 +W:    http://wireless.kernel.org/en/developers/Documentation/mac80211/RateControl/PID
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
  S:    Maintained
@@@ -4416,6 -4425,13 +4425,13 @@@ S:    Orpha
  F:    drivers/video/matrox/matroxfb_*
  F:    include/linux/matroxfb.h
  
+ MAX16065 HARDWARE MONITOR DRIVER
+ M:    Guenter Roeck <linux@roeck-us.net>
+ L:    lm-sensors@lm-sensors.org
+ S:    Maintained
+ F:    Documentation/hwmon/max16065
+ F:    drivers/hwmon/max16065.c
  MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
  M:    "Hans J. Koch" <hjk@hansjkoch.de>
  L:    lm-sensors@lm-sensors.org
@@@ -5032,7 -5048,7 +5048,7 @@@ F:      fs/ocfs2
  
  ORINOCO DRIVER
  L:    linux-wireless@vger.kernel.org
 -W:    http://linuxwireless.org/en/users/Drivers/orinoco
 +W:    http://wireless.kernel.org/en/users/Drivers/orinoco
  W:    http://www.nongnu.org/orinoco/
  S:    Orphan
  F:    drivers/net/wireless/orinoco/
@@@ -5154,7 -5170,7 +5170,7 @@@ F:      drivers/leds/leds-pca9532.
  F:    include/linux/leds-pca9532.h
  
  PCA9541 I2C BUS MASTER SELECTOR DRIVER
- M:    Guenter Roeck <guenter.roeck@ericsson.com>
+ M:    Guenter Roeck <linux@roeck-us.net>
  L:    linux-i2c@vger.kernel.org
  S:    Maintained
  F:    drivers/i2c/muxes/i2c-mux-pca9541.c
@@@ -5174,7 -5190,7 +5190,7 @@@ S:      Maintaine
  F:    drivers/firmware/pcdp.*
  
  PCI ERROR RECOVERY
- M:     Linas Vepstas <linasvepstas@gmail.com>
+ M:    Linas Vepstas <linasvepstas@gmail.com>
  L:    linux-pci@vger.kernel.org
  S:    Supported
  F:    Documentation/PCI/pci-error-recovery.txt
@@@ -5304,7 -5320,7 +5320,7 @@@ F:      drivers/video/fb-puv3.
  F:    drivers/rtc/rtc-puv3.c
  
  PMBUS HARDWARE MONITORING DRIVERS
- M:    Guenter Roeck <guenter.roeck@ericsson.com>
+ M:    Guenter Roeck <linux@roeck-us.net>
  L:    lm-sensors@lm-sensors.org
  W:    http://www.lm-sensors.org/
  W:    http://www.roeck-us.net/linux/drivers/
@@@ -5737,7 -5753,7 +5753,7 @@@ F:      net/rose
  RTL8180 WIRELESS DRIVER
  M:    "John W. Linville" <linville@tuxdriver.com>
  L:    linux-wireless@vger.kernel.org
 -W:    http://linuxwireless.org/
 +W:    http://wireless.kernel.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
  S:    Maintained
  F:    drivers/net/wireless/rtl818x/rtl8180/
@@@ -5747,7 -5763,7 +5763,7 @@@ M:      Herton Ronaldo Krzesinski <herton@ca
  M:    Hin-Tak Leung <htl10@users.sourceforge.net>
  M:    Larry Finger <Larry.Finger@lwfinger.net>
  L:    linux-wireless@vger.kernel.org
 -W:    http://linuxwireless.org/
 +W:    http://wireless.kernel.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
  S:    Maintained
  F:    drivers/net/wireless/rtl818x/rtl8187/
@@@ -5756,7 -5772,7 +5772,7 @@@ RTL8192CE WIRELESS DRIVE
  M:    Larry Finger <Larry.Finger@lwfinger.net>
  M:    Chaoming Li <chaoming_li@realsil.com.cn>
  L:    linux-wireless@vger.kernel.org
 -W:    http://linuxwireless.org/
 +W:    http://wireless.kernel.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
  S:    Maintained
  F:    drivers/net/wireless/rtlwifi/
@@@ -7299,11 -7315,11 +7315,11 @@@ F:   Documentation/DocBook/uio-howto.tmp
  F:    drivers/uio/
  F:    include/linux/uio*.h
  
- UTIL-LINUX-NG PACKAGE
+ UTIL-LINUX PACKAGE
  M:    Karel Zak <kzak@redhat.com>
- L:    util-linux-ng@vger.kernel.org
- W:    http://kernel.org/~kzak/util-linux-ng/
- T:    git git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git
+ L:    util-linux@vger.kernel.org
+ W:    http://en.wikipedia.org/wiki/Util-linux
+ T:    git git://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
  S:    Maintained
  
  UVESAFB DRIVER
  
  #include "c_can.h"
  
 +/* Number of interface registers */
 +#define IF_ENUM_REG_LEN               11
 +#define C_CAN_IFACE(reg, iface)       (C_CAN_IF1_##reg + (iface) * IF_ENUM_REG_LEN)
 +
  /* control register */
  #define CONTROL_TEST          BIT(7)
  #define CONTROL_CCE           BIT(6)
@@@ -213,10 -209,10 +213,10 @@@ static inline int get_tx_echo_msg_obj(c
                        C_CAN_MSG_OBJ_TX_FIRST;
  }
  
 -static u32 c_can_read_reg32(struct c_can_priv *priv, void *reg)
 +static u32 c_can_read_reg32(struct c_can_priv *priv, enum reg index)
  {
 -      u32 val = priv->read_reg(priv, reg);
 -      val |= ((u32) priv->read_reg(priv, reg + 2)) << 16;
 +      u32 val = priv->read_reg(priv, index);
 +      val |= ((u32) priv->read_reg(priv, index + 1)) << 16;
        return val;
  }
  
@@@ -224,14 -220,14 +224,14 @@@ static void c_can_enable_all_interrupts
                                                int enable)
  {
        unsigned int cntrl_save = priv->read_reg(priv,
 -                                              &priv->regs->control);
 +                                              C_CAN_CTRL_REG);
  
        if (enable)
                cntrl_save |= (CONTROL_SIE | CONTROL_EIE | CONTROL_IE);
        else
                cntrl_save &= ~(CONTROL_EIE | CONTROL_IE | CONTROL_SIE);
  
 -      priv->write_reg(priv, &priv->regs->control, cntrl_save);
 +      priv->write_reg(priv, C_CAN_CTRL_REG, cntrl_save);
  }
  
  static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface)
        int count = MIN_TIMEOUT_VALUE;
  
        while (count && priv->read_reg(priv,
 -                              &priv->regs->ifregs[iface].com_req) &
 +                              C_CAN_IFACE(COMREQ_REG, iface)) &
                                IF_COMR_BUSY) {
                count--;
                udelay(1);
@@@ -262,9 -258,9 +262,9 @@@ static inline void c_can_object_get(str
         * register and message RAM must be complete in 6 CAN-CLK
         * period.
         */
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask,
 +      priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface),
                        IFX_WRITE_LOW_16BIT(mask));
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].com_req,
 +      priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface),
                        IFX_WRITE_LOW_16BIT(objno));
  
        if (c_can_msg_obj_is_busy(priv, iface))
@@@ -282,9 -278,9 +282,9 @@@ static inline void c_can_object_put(str
         * register and message RAM must be complete in 6 CAN-CLK
         * period.
         */
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask,
 +      priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface),
                        (IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask)));
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].com_req,
 +      priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface),
                        IFX_WRITE_LOW_16BIT(objno));
  
        if (c_can_msg_obj_is_busy(priv, iface))
@@@ -310,18 -306,18 +310,18 @@@ static void c_can_write_msg_object(stru
  
        flags |= IF_ARB_MSGVAL;
  
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].arb1,
 +      priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface),
                                IFX_WRITE_LOW_16BIT(id));
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, flags |
 +      priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), flags |
                                IFX_WRITE_HIGH_16BIT(id));
  
        for (i = 0; i < frame->can_dlc; i += 2) {
 -              priv->write_reg(priv, &priv->regs->ifregs[iface].data[i / 2],
 +              priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
                                frame->data[i] | (frame->data[i + 1] << 8));
        }
  
        /* enable interrupt for this message object */
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl,
 +      priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface),
                        IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB |
                        frame->can_dlc);
        c_can_object_put(dev, iface, objno, IF_COMM_ALL);
@@@ -333,7 -329,7 +333,7 @@@ static inline void c_can_mark_rx_msg_ob
  {
        struct c_can_priv *priv = netdev_priv(dev);
  
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl,
 +      priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface),
                        ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND));
        c_can_object_put(dev, iface, obj, IF_COMM_CONTROL);
  
@@@ -347,7 -343,7 +347,7 @@@ static inline void c_can_activate_all_l
        struct c_can_priv *priv = netdev_priv(dev);
  
        for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) {
 -              priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl,
 +              priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface),
                                ctrl_mask & ~(IF_MCONT_MSGLST |
                                        IF_MCONT_INTPND | IF_MCONT_NEWDAT));
                c_can_object_put(dev, iface, i, IF_COMM_CONTROL);
@@@ -360,7 -356,7 +360,7 @@@ static inline void c_can_activate_rx_ms
  {
        struct c_can_priv *priv = netdev_priv(dev);
  
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl,
 +      priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface),
                        ctrl_mask & ~(IF_MCONT_MSGLST |
                                IF_MCONT_INTPND | IF_MCONT_NEWDAT));
        c_can_object_put(dev, iface, obj, IF_COMM_CONTROL);
@@@ -378,7 -374,7 +378,7 @@@ static void c_can_handle_lost_msg_obj(s
  
        c_can_object_get(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST);
  
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl,
 +      priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface),
                        IF_MCONT_CLR_MSGLST);
  
        c_can_object_put(dev, 0, objno, IF_COMM_CONTROL);
@@@ -414,8 -410,8 +414,8 @@@ static int c_can_read_msg_object(struc
  
        frame->can_dlc = get_can_dlc(ctrl & 0x0F);
  
 -      flags = priv->read_reg(priv, &priv->regs->ifregs[iface].arb2);
 -      val = priv->read_reg(priv, &priv->regs->ifregs[iface].arb1) |
 +      flags = priv->read_reg(priv, C_CAN_IFACE(ARB2_REG, iface));
 +      val = priv->read_reg(priv, C_CAN_IFACE(ARB1_REG, iface)) |
                (flags << 16);
  
        if (flags & IF_ARB_MSGXTD)
        else {
                for (i = 0; i < frame->can_dlc; i += 2) {
                        data = priv->read_reg(priv,
 -                              &priv->regs->ifregs[iface].data[i / 2]);
 +                              C_CAN_IFACE(DATA1_REG, iface) + i / 2);
                        frame->data[i] = data;
                        frame->data[i + 1] = data >> 8;
                }
@@@ -448,40 -444,40 +448,40 @@@ static void c_can_setup_receive_object(
  {
        struct c_can_priv *priv = netdev_priv(dev);
  
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].mask1,
 +      priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface),
                        IFX_WRITE_LOW_16BIT(mask));
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].mask2,
 +      priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface),
                        IFX_WRITE_HIGH_16BIT(mask));
  
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].arb1,
 +      priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface),
                        IFX_WRITE_LOW_16BIT(id));
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].arb2,
 +      priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface),
                        (IF_ARB_MSGVAL | IFX_WRITE_HIGH_16BIT(id)));
  
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, mcont);
 +      priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont);
        c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST);
  
        netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno,
 -                      c_can_read_reg32(priv, &priv->regs->msgval1));
 +                      c_can_read_reg32(priv, C_CAN_MSGVAL1_REG));
  }
  
  static void c_can_inval_msg_object(struct net_device *dev, int iface, int objno)
  {
        struct c_can_priv *priv = netdev_priv(dev);
  
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, 0);
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, 0);
 -      priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, 0);
 +      priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0);
 +      priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0);
 +      priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
  
        c_can_object_put(dev, iface, objno, IF_COMM_ARB | IF_COMM_CONTROL);
  
        netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno,
 -                      c_can_read_reg32(priv, &priv->regs->msgval1));
 +                      c_can_read_reg32(priv, C_CAN_MSGVAL1_REG));
  }
  
  static inline int c_can_is_next_tx_obj_busy(struct c_can_priv *priv, int objno)
  {
 -      int val = c_can_read_reg32(priv, &priv->regs->txrqst1);
 +      int val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG);
  
        /*
         * as transmission request register's bit n-1 corresponds to
@@@ -544,12 -540,12 +544,12 @@@ static int c_can_set_bittiming(struct n
        netdev_info(dev,
                "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe);
  
 -      ctrl_save = priv->read_reg(priv, &priv->regs->control);
 -      priv->write_reg(priv, &priv->regs->control,
 +      ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG);
 +      priv->write_reg(priv, C_CAN_CTRL_REG,
                        ctrl_save | CONTROL_CCE | CONTROL_INIT);
 -      priv->write_reg(priv, &priv->regs->btr, reg_btr);
 -      priv->write_reg(priv, &priv->regs->brp_ext, reg_brpe);
 -      priv->write_reg(priv, &priv->regs->control, ctrl_save);
 +      priv->write_reg(priv, C_CAN_BTR_REG, reg_btr);
 +      priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe);
 +      priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save);
  
        return 0;
  }
@@@ -591,36 -587,36 +591,36 @@@ static void c_can_chip_config(struct ne
        struct c_can_priv *priv = netdev_priv(dev);
  
        /* enable automatic retransmission */
 -      priv->write_reg(priv, &priv->regs->control,
 +      priv->write_reg(priv, C_CAN_CTRL_REG,
                        CONTROL_ENABLE_AR);
  
-       if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY &
-                                       CAN_CTRLMODE_LOOPBACK)) {
+       if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) &&
+           (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) {
                /* loopback + silent mode : useful for hot self-test */
 -              priv->write_reg(priv, &priv->regs->control, CONTROL_EIE |
 +              priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE |
                                CONTROL_SIE | CONTROL_IE | CONTROL_TEST);
 -              priv->write_reg(priv, &priv->regs->test,
 +              priv->write_reg(priv, C_CAN_TEST_REG,
                                TEST_LBACK | TEST_SILENT);
        } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
                /* loopback mode : useful for self-test function */
 -              priv->write_reg(priv, &priv->regs->control, CONTROL_EIE |
 +              priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE |
                                CONTROL_SIE | CONTROL_IE | CONTROL_TEST);
 -              priv->write_reg(priv, &priv->regs->test, TEST_LBACK);
 +              priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK);
        } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
                /* silent mode : bus-monitoring mode */
 -              priv->write_reg(priv, &priv->regs->control, CONTROL_EIE |
 +              priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE |
                                CONTROL_SIE | CONTROL_IE | CONTROL_TEST);
 -              priv->write_reg(priv, &priv->regs->test, TEST_SILENT);
 +              priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT);
        } else
                /* normal mode*/
 -              priv->write_reg(priv, &priv->regs->control,
 +              priv->write_reg(priv, C_CAN_CTRL_REG,
                                CONTROL_EIE | CONTROL_SIE | CONTROL_IE);
  
        /* configure message objects */
        c_can_configure_msg_objects(dev);
  
        /* set a `lec` value so that we can check for updates later */
 -      priv->write_reg(priv, &priv->regs->status, LEC_UNUSED);
 +      priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
  
        /* set bittiming params */
        c_can_set_bittiming(dev);
@@@ -673,7 -669,7 +673,7 @@@ static int c_can_get_berr_counter(cons
        unsigned int reg_err_counter;
        struct c_can_priv *priv = netdev_priv(dev);
  
 -      reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt);
 +      reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
        bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
                                ERR_CNT_REC_SHIFT;
        bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK;
@@@ -701,12 -697,12 +701,12 @@@ static void c_can_do_tx(struct net_devi
  
        for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) {
                msg_obj_no = get_tx_echo_msg_obj(priv);
 -              val = c_can_read_reg32(priv, &priv->regs->txrqst1);
 +              val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG);
                if (!(val & (1 << (msg_obj_no - 1)))) {
                        can_get_echo_skb(dev,
                                        msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
                        stats->tx_bytes += priv->read_reg(priv,
 -                                      &priv->regs->ifregs[0].msg_cntrl)
 +                                      C_CAN_IFACE(MSGCTRL_REG, 0))
                                        & IF_MCONT_DLC_MASK;
                        stats->tx_packets++;
                        c_can_inval_msg_object(dev, 0, msg_obj_no);
@@@ -748,11 -744,11 +748,11 @@@ static int c_can_do_rx_poll(struct net_
        u32 num_rx_pkts = 0;
        unsigned int msg_obj, msg_ctrl_save;
        struct c_can_priv *priv = netdev_priv(dev);
 -      u32 val = c_can_read_reg32(priv, &priv->regs->intpnd1);
 +      u32 val = c_can_read_reg32(priv, C_CAN_INTPND1_REG);
  
        for (msg_obj = C_CAN_MSG_OBJ_RX_FIRST;
                        msg_obj <= C_CAN_MSG_OBJ_RX_LAST && quota > 0;
 -                      val = c_can_read_reg32(priv, &priv->regs->intpnd1),
 +                      val = c_can_read_reg32(priv, C_CAN_INTPND1_REG),
                        msg_obj++) {
                /*
                 * as interrupt pending register's bit n-1 corresponds to
                        c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL &
                                        ~IF_COMM_TXRQST);
                        msg_ctrl_save = priv->read_reg(priv,
 -                                      &priv->regs->ifregs[0].msg_cntrl);
 +                                      C_CAN_IFACE(MSGCTRL_REG, 0));
  
                        if (msg_ctrl_save & IF_MCONT_EOB)
                                return num_rx_pkts;
@@@ -823,7 -819,7 +823,7 @@@ static int c_can_handle_state_change(st
                return 0;
  
        c_can_get_berr_counter(dev, &bec);
 -      reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt);
 +      reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
        rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >>
                                ERR_CNT_RP_SHIFT;
  
@@@ -939,7 -935,7 +939,7 @@@ static int c_can_handle_bus_err(struct 
        }
  
        /* set a `lec` value so that we can check for updates later */
 -      priv->write_reg(priv, &priv->regs->status, LEC_UNUSED);
 +      priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
  
        netif_receive_skb(skb);
        stats->rx_packets++;
@@@ -963,15 -959,15 +963,15 @@@ static int c_can_poll(struct napi_struc
        /* status events have the highest priority */
        if (irqstatus == STATUS_INTERRUPT) {
                priv->current_status = priv->read_reg(priv,
 -                                      &priv->regs->status);
 +                                      C_CAN_STS_REG);
  
                /* handle Tx/Rx events */
                if (priv->current_status & STATUS_TXOK)
 -                      priv->write_reg(priv, &priv->regs->status,
 +                      priv->write_reg(priv, C_CAN_STS_REG,
                                        priv->current_status & ~STATUS_TXOK);
  
                if (priv->current_status & STATUS_RXOK)
 -                      priv->write_reg(priv, &priv->regs->status,
 +                      priv->write_reg(priv, C_CAN_STS_REG,
                                        priv->current_status & ~STATUS_RXOK);
  
                /* handle state changes */
@@@ -1037,7 -1033,7 +1037,7 @@@ static irqreturn_t c_can_isr(int irq, v
        struct net_device *dev = (struct net_device *)dev_id;
        struct c_can_priv *priv = netdev_priv(dev);
  
 -      priv->irqstatus = priv->read_reg(priv, &priv->regs->interrupt);
 +      priv->irqstatus = priv->read_reg(priv, C_CAN_INT_REG);
        if (!priv->irqstatus)
                return IRQ_NONE;
  
@@@ -479,7 -479,7 +479,7 @@@ qlcnic_init_pci_info(struct qlcnic_adap
  
        for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
                pfn = pci_info[i].id;
-               if (pfn > QLCNIC_MAX_PCI_FUNC) {
+               if (pfn >= QLCNIC_MAX_PCI_FUNC) {
                        ret = QL_STATUS_INVALID_PARAM;
                        goto err_eswitch;
                }
@@@ -1136,8 -1136,6 +1136,8 @@@ static in
  __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
  {
        int ring;
 +      u32 capab2;
 +
        struct qlcnic_host_rds_ring *rds_ring;
  
        if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
        if (qlcnic_set_eswitch_port_config(adapter))
                return -EIO;
  
 +      if (adapter->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) {
 +              capab2 = QLCRD32(adapter, CRB_FW_CAPABILITIES_2);
 +              if (capab2 & QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG)
 +                      adapter->flags |= QLCNIC_FW_LRO_MSS_CAP;
 +      }
 +
        if (qlcnic_fw_create_ctx(adapter))
                return -EIO;
  
@@@ -1223,7 -1215,6 +1223,7 @@@ __qlcnic_down(struct qlcnic_adapter *ad
        qlcnic_napi_disable(adapter);
  
        qlcnic_fw_destroy_ctx(adapter);
 +      adapter->flags &= ~QLCNIC_FW_LRO_MSS_CAP;
  
        qlcnic_reset_rx_buffers_list(adapter);
        qlcnic_release_tx_buffers(adapter);
@@@ -2033,7 -2024,6 +2033,7 @@@ qlcnic_tx_pkt(struct qlcnic_adapter *ad
                vh = (struct vlan_ethhdr *)skb->data;
                flags = FLAGS_VLAN_TAGGED;
                vlan_tci = vh->h_vlan_TCI;
 +              protocol = ntohs(vh->h_vlan_encapsulated_proto);
        } else if (vlan_tx_tag_present(skb)) {
                flags = FLAGS_VLAN_OOB;
                vlan_tci = vlan_tx_tag_get(skb);
diff --combined include/net/ip6_fib.h
@@@ -107,7 -107,7 +107,7 @@@ struct rt6_info 
        u32                             rt6i_peer_genid;
  
        struct inet6_dev                *rt6i_idev;
 -      struct inet_peer                *rt6i_peer;
 +      unsigned long                   _rt6i_peer;
  
  #ifdef CONFIG_XFRM
        u32                             rt6i_flow_cache_genid;
        u8                              rt6i_protocol;
  };
  
 +static inline struct inet_peer *rt6_peer_ptr(struct rt6_info *rt)
 +{
 +      return inetpeer_ptr(rt->_rt6i_peer);
 +}
 +
 +static inline bool rt6_has_peer(struct rt6_info *rt)
 +{
 +      return inetpeer_ptr_is_peer(rt->_rt6i_peer);
 +}
 +
 +static inline void __rt6_set_peer(struct rt6_info *rt, struct inet_peer *peer)
 +{
 +      __inetpeer_ptr_set_peer(&rt->_rt6i_peer, peer);
 +}
 +
 +static inline bool rt6_set_peer(struct rt6_info *rt, struct inet_peer *peer)
 +{
 +      return inetpeer_ptr_set_peer(&rt->_rt6i_peer, peer);
 +}
 +
 +static inline void rt6_init_peer(struct rt6_info *rt, struct inet_peer_base *base)
 +{
 +      inetpeer_init_ptr(&rt->_rt6i_peer, base);
 +}
 +
 +static inline void rt6_transfer_peer(struct rt6_info *rt, struct rt6_info *ort)
 +{
 +      inetpeer_transfer_peer(&rt->_rt6i_peer, &ort->_rt6i_peer);
 +}
 +
  static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
  {
        return ((struct rt6_info *)dst)->rt6i_idev;
@@@ -237,7 -207,6 +237,7 @@@ struct fib6_table 
        u32                     tb6_id;
        rwlock_t                tb6_lock;
        struct fib6_node        tb6_root;
 +      struct inet_peer_base   tb6_peers;
  };
  
  #define RT6_TABLE_UNSPEC      RT_TABLE_UNSPEC
@@@ -302,6 -271,8 +302,8 @@@ extern void                        fib6_run_gc(unsigned lon
  extern void                   fib6_gc_cleanup(void);
  
  extern int                    fib6_init(void);
+ extern int                    fib6_init_late(void);
+ extern void                   fib6_cleanup_late(void);
  
  #ifdef CONFIG_IPV6_MULTIPLE_TABLES
  extern int                    fib6_rules_init(void);
diff --combined net/core/dev.c
@@@ -2089,25 -2089,6 +2089,6 @@@ static int dev_gso_segment(struct sk_bu
        return 0;
  }
  
- /*
-  * Try to orphan skb early, right before transmission by the device.
-  * We cannot orphan skb if tx timestamp is requested or the sk-reference
-  * is needed on driver level for other reasons, e.g. see net/can/raw.c
-  */
- static inline void skb_orphan_try(struct sk_buff *skb)
- {
-       struct sock *sk = skb->sk;
-       if (sk && !skb_shinfo(skb)->tx_flags) {
-               /* skb_tx_hash() wont be able to get sk.
-                * We copy sk_hash into skb->rxhash
-                */
-               if (!skb->rxhash)
-                       skb->rxhash = sk->sk_hash;
-               skb_orphan(skb);
-       }
- }
  static bool can_checksum_protocol(netdev_features_t features, __be16 protocol)
  {
        return ((features & NETIF_F_GEN_CSUM) ||
@@@ -2193,8 -2174,6 +2174,6 @@@ int dev_hard_start_xmit(struct sk_buff 
                if (!list_empty(&ptype_all))
                        dev_queue_xmit_nit(skb, dev);
  
-               skb_orphan_try(skb);
                features = netif_skb_features(skb);
  
                if (vlan_tx_tag_present(skb) &&
@@@ -2304,7 -2283,7 +2283,7 @@@ u16 __skb_tx_hash(const struct net_devi
        if (skb->sk && skb->sk->sk_hash)
                hash = skb->sk->sk_hash;
        else
-               hash = (__force u16) skb->protocol ^ skb->rxhash;
+               hash = (__force u16) skb->protocol;
        hash = jhash_1word(hash, hashrnd);
  
        return (u16) (((u64) hash * qcount) >> 32) + qoffset;
@@@ -2476,23 -2455,6 +2455,23 @@@ static DEFINE_PER_CPU(int, xmit_recursi
  #define RECURSION_LIMIT 10
  
  /**
 + *    dev_loopback_xmit - loop back @skb
 + *    @skb: buffer to transmit
 + */
 +int dev_loopback_xmit(struct sk_buff *skb)
 +{
 +      skb_reset_mac_header(skb);
 +      __skb_pull(skb, skb_network_offset(skb));
 +      skb->pkt_type = PACKET_LOOPBACK;
 +      skb->ip_summed = CHECKSUM_UNNECESSARY;
 +      WARN_ON(!skb_dst(skb));
 +      skb_dst_force(skb);
 +      netif_rx_ni(skb);
 +      return 0;
 +}
 +EXPORT_SYMBOL(dev_loopback_xmit);
 +
 +/**
   *    dev_queue_xmit - transmit a buffer
   *    @skb: buffer to transmit
   *
diff --combined net/ipv6/ip6_fib.c
@@@ -197,7 -197,6 +197,7 @@@ static struct fib6_table *fib6_alloc_ta
                table->tb6_id = id;
                table->tb6_root.leaf = net->ipv6.ip6_null_entry;
                table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
 +              inet_peer_base_init(&table->tb6_peers);
        }
  
        return table;
@@@ -1634,7 -1633,6 +1634,7 @@@ static int __net_init fib6_net_init(str
        net->ipv6.fib6_main_tbl->tb6_root.leaf = net->ipv6.ip6_null_entry;
        net->ipv6.fib6_main_tbl->tb6_root.fn_flags =
                RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
 +      inet_peer_base_init(&net->ipv6.fib6_main_tbl->tb6_peers);
  
  #ifdef CONFIG_IPV6_MULTIPLE_TABLES
        net->ipv6.fib6_local_tbl = kzalloc(sizeof(*net->ipv6.fib6_local_tbl),
        net->ipv6.fib6_local_tbl->tb6_root.leaf = net->ipv6.ip6_null_entry;
        net->ipv6.fib6_local_tbl->tb6_root.fn_flags =
                RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
 +      inet_peer_base_init(&net->ipv6.fib6_local_tbl->tb6_peers);
  #endif
        fib6_tables_init(net);
  
@@@ -1669,10 -1666,8 +1669,10 @@@ static void fib6_net_exit(struct net *n
        del_timer_sync(&net->ipv6.ip6_fib_timer);
  
  #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 +      inetpeer_invalidate_tree(&net->ipv6.fib6_local_tbl->tb6_peers);
        kfree(net->ipv6.fib6_local_tbl);
  #endif
 +      inetpeer_invalidate_tree(&net->ipv6.fib6_main_tbl->tb6_peers);
        kfree(net->ipv6.fib6_main_tbl);
        kfree(net->ipv6.fib_table_hash);
        kfree(net->ipv6.rt6_stats);
@@@ -1697,21 -1692,25 +1697,25 @@@ int __init fib6_init(void
        ret = register_pernet_subsys(&fib6_net_ops);
        if (ret)
                goto out_kmem_cache_create;
-       ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib,
-                             NULL);
-       if (ret)
-               goto out_unregister_subsys;
  out:
        return ret;
  
- out_unregister_subsys:
-       unregister_pernet_subsys(&fib6_net_ops);
  out_kmem_cache_create:
        kmem_cache_destroy(fib6_node_kmem);
        goto out;
  }
  
+ int __init fib6_init_late(void)
+ {
+       return __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib,
+                              NULL);
+ }
+ void fib6_cleanup_late(void)
+ {
+       rtnl_unregister(PF_INET6, RTM_GETROUTE);
+ }
  void fib6_gc_cleanup(void)
  {
        unregister_pernet_subsys(&fib6_net_ops);
diff --combined net/ipv6/route.c
@@@ -99,7 -99,10 +99,7 @@@ static u32 *ipv6_cow_metrics(struct dst
        if (!(rt->dst.flags & DST_HOST))
                return NULL;
  
 -      if (!rt->rt6i_peer)
 -              rt6_bind_peer(rt, 1);
 -
 -      peer = rt->rt6i_peer;
 +      peer = rt6_get_peer_create(rt);
        if (peer) {
                u32 *old_p = __DST_METRICS_PTR(old);
                unsigned long prev, new;
@@@ -258,19 -261,16 +258,19 @@@ static struct rt6_info ip6_blk_hole_ent
  #endif
  
  /* allocate dst with ip6_dst_ops */
 -static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops,
 +static inline struct rt6_info *ip6_dst_alloc(struct net *net,
                                             struct net_device *dev,
 -                                           int flags)
 +                                           int flags,
 +                                           struct fib6_table *table)
  {
 -      struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags);
 +      struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
 +                                      0, 0, flags);
  
 -      if (rt)
 +      if (rt) {
                memset(&rt->rt6i_table, 0,
                       sizeof(*rt) - sizeof(struct dst_entry));
 -
 +              rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
 +      }
        return rt;
  }
  
@@@ -278,6 -278,7 +278,6 @@@ static void ip6_dst_destroy(struct dst_
  {
        struct rt6_info *rt = (struct rt6_info *)dst;
        struct inet6_dev *idev = rt->rt6i_idev;
 -      struct inet_peer *peer = rt->rt6i_peer;
  
        if (!(rt->dst.flags & DST_HOST))
                dst_destroy_metrics_generic(dst);
        if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from)
                dst_release(dst->from);
  
 -      if (peer) {
 -              rt->rt6i_peer = NULL;
 +      if (rt6_has_peer(rt)) {
 +              struct inet_peer *peer = rt6_peer_ptr(rt);
                inet_putpeer(peer);
        }
  }
@@@ -305,20 -306,13 +305,20 @@@ static u32 rt6_peer_genid(void
  
  void rt6_bind_peer(struct rt6_info *rt, int create)
  {
 +      struct inet_peer_base *base;
        struct inet_peer *peer;
  
 -      peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create);
 -      if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL)
 -              inet_putpeer(peer);
 -      else
 -              rt->rt6i_peer_genid = rt6_peer_genid();
 +      base = inetpeer_base_ptr(rt->_rt6i_peer);
 +      if (!base)
 +              return;
 +
 +      peer = inet_getpeer_v6(base, &rt->rt6i_dst.addr, create);
 +      if (peer) {
 +              if (!rt6_set_peer(rt, peer))
 +                      inet_putpeer(peer);
 +              else
 +                      rt->rt6i_peer_genid = rt6_peer_genid();
 +      }
  }
  
  static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
@@@ -958,7 -952,6 +958,7 @@@ struct dst_entry *ip6_blackhole_route(s
        rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0);
        if (rt) {
                memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry));
 +              rt6_init_peer(rt, net->ipv6.peers);
  
                new = &rt->dst;
  
@@@ -1003,7 -996,7 +1003,7 @@@ static struct dst_entry *ip6_dst_check(
  
        if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
                if (rt->rt6i_peer_genid != rt6_peer_genid()) {
 -                      if (!rt->rt6i_peer)
 +                      if (!rt6_has_peer(rt))
                                rt6_bind_peer(rt, 0);
                        rt->rt6i_peer_genid = rt6_peer_genid();
                }
@@@ -1049,10 -1042,7 +1049,10 @@@ static void ip6_rt_update_pmtu(struct d
  {
        struct rt6_info *rt6 = (struct rt6_info*)dst;
  
 +      dst_confirm(dst);
        if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) {
 +              struct net *net = dev_net(dst->dev);
 +
                rt6->rt6i_flags |= RTF_MODIFIED;
                if (mtu < IPV6_MIN_MTU) {
                        u32 features = dst_metric(dst, RTAX_FEATURES);
                        dst_metric_set(dst, RTAX_FEATURES, features);
                }
                dst_metric_set(dst, RTAX_MTU, mtu);
 +              rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires);
        }
  }
  
 +void ip6_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
 +                   int oif, __be32 mark)
 +{
 +      const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;
 +      struct dst_entry *dst;
 +      struct flowi6 fl6;
 +
 +      memset(&fl6, 0, sizeof(fl6));
 +      fl6.flowi6_oif = oif;
 +      fl6.flowi6_mark = mark;
 +      fl6.flowi6_flags = FLOWI_FLAG_PRECOW_METRICS;
 +      fl6.daddr = iph->daddr;
 +      fl6.saddr = iph->saddr;
 +      fl6.flowlabel = (*(__be32 *) iph) & IPV6_FLOWINFO_MASK;
 +
 +      dst = ip6_route_output(net, NULL, &fl6);
 +      if (!dst->error)
 +              ip6_rt_update_pmtu(dst, ntohl(mtu));
 +      dst_release(dst);
 +}
 +EXPORT_SYMBOL_GPL(ip6_update_pmtu);
 +
 +void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu)
 +{
 +      ip6_update_pmtu(skb, sock_net(sk), mtu,
 +                      sk->sk_bound_dev_if, sk->sk_mark);
 +}
 +EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu);
 +
  static unsigned int ip6_default_advmss(const struct dst_entry *dst)
  {
        struct net_device *dev = dst->dev;
@@@ -1150,7 -1110,7 +1150,7 @@@ struct dst_entry *icmp6_dst_alloc(struc
        if (unlikely(!idev))
                return ERR_PTR(-ENODEV);
  
 -      rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0);
 +      rt = ip6_dst_alloc(net, dev, 0, NULL);
        if (unlikely(!rt)) {
                in6_dev_put(idev);
                dst = ERR_PTR(-ENOMEM);
@@@ -1332,7 -1292,7 +1332,7 @@@ int ip6_route_add(struct fib6_config *c
        if (!table)
                goto out;
  
 -      rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT);
 +      rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT, table);
  
        if (!rt) {
                err = -ENOMEM;
  }
  
  /*
 - *    Handle ICMP "packet too big" messages
 - *    i.e. Path MTU discovery
 - */
 -
 -static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr *saddr,
 -                           struct net *net, u32 pmtu, int ifindex)
 -{
 -      struct rt6_info *rt, *nrt;
 -      int allfrag = 0;
 -again:
 -      rt = rt6_lookup(net, daddr, saddr, ifindex, 0);
 -      if (!rt)
 -              return;
 -
 -      if (rt6_check_expired(rt)) {
 -              ip6_del_rt(rt);
 -              goto again;
 -      }
 -
 -      if (pmtu >= dst_mtu(&rt->dst))
 -              goto out;
 -
 -      if (pmtu < IPV6_MIN_MTU) {
 -              /*
 -               * According to RFC2460, PMTU is set to the IPv6 Minimum Link
 -               * MTU (1280) and a fragment header should always be included
 -               * after a node receiving Too Big message reporting PMTU is
 -               * less than the IPv6 Minimum Link MTU.
 -               */
 -              pmtu = IPV6_MIN_MTU;
 -              allfrag = 1;
 -      }
 -
 -      /* New mtu received -> path was valid.
 -         They are sent only in response to data packets,
 -         so that this nexthop apparently is reachable. --ANK
 -       */
 -      dst_confirm(&rt->dst);
 -
 -      /* Host route. If it is static, it would be better
 -         not to override it, but add new one, so that
 -         when cache entry will expire old pmtu
 -         would return automatically.
 -       */
 -      if (rt->rt6i_flags & RTF_CACHE) {
 -              dst_metric_set(&rt->dst, RTAX_MTU, pmtu);
 -              if (allfrag) {
 -                      u32 features = dst_metric(&rt->dst, RTAX_FEATURES);
 -                      features |= RTAX_FEATURE_ALLFRAG;
 -                      dst_metric_set(&rt->dst, RTAX_FEATURES, features);
 -              }
 -              rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires);
 -              rt->rt6i_flags |= RTF_MODIFIED;
 -              goto out;
 -      }
 -
 -      /* Network route.
 -         Two cases are possible:
 -         1. It is connected route. Action: COW
 -         2. It is gatewayed route or NONEXTHOP route. Action: clone it.
 -       */
 -      if (!dst_get_neighbour_noref_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
 -              nrt = rt6_alloc_cow(rt, daddr, saddr);
 -      else
 -              nrt = rt6_alloc_clone(rt, daddr);
 -
 -      if (nrt) {
 -              dst_metric_set(&nrt->dst, RTAX_MTU, pmtu);
 -              if (allfrag) {
 -                      u32 features = dst_metric(&nrt->dst, RTAX_FEATURES);
 -                      features |= RTAX_FEATURE_ALLFRAG;
 -                      dst_metric_set(&nrt->dst, RTAX_FEATURES, features);
 -              }
 -
 -              /* According to RFC 1981, detecting PMTU increase shouldn't be
 -               * happened within 5 mins, the recommended timer is 10 mins.
 -               * Here this route expiration time is set to ip6_rt_mtu_expires
 -               * which is 10 mins. After 10 mins the decreased pmtu is expired
 -               * and detecting PMTU increase will be automatically happened.
 -               */
 -              rt6_update_expires(nrt, net->ipv6.sysctl.ip6_rt_mtu_expires);
 -              nrt->rt6i_flags |= RTF_DYNAMIC;
 -              ip6_ins_rt(nrt);
 -      }
 -out:
 -      dst_release(&rt->dst);
 -}
 -
 -void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *saddr,
 -                      struct net_device *dev, u32 pmtu)
 -{
 -      struct net *net = dev_net(dev);
 -
 -      /*
 -       * RFC 1981 states that a node "MUST reduce the size of the packets it
 -       * is sending along the path" that caused the Packet Too Big message.
 -       * Since it's not possible in the general case to determine which
 -       * interface was used to send the original packet, we update the MTU
 -       * on the interface that will be used to send future packets. We also
 -       * update the MTU on the interface that received the Packet Too Big in
 -       * case the original packet was forced out that interface with
 -       * SO_BINDTODEVICE or similar. This is the next best thing to the
 -       * correct behaviour, which would be to update the MTU on all
 -       * interfaces.
 -       */
 -      rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0);
 -      rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex);
 -}
 -
 -/*
   *    Misc support functions
   */
  
@@@ -1744,8 -1814,8 +1744,8 @@@ static struct rt6_info *ip6_rt_copy(str
                                    const struct in6_addr *dest)
  {
        struct net *net = dev_net(ort->dst.dev);
 -      struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
 -                                          ort->dst.dev, 0);
 +      struct rt6_info *rt = ip6_dst_alloc(net, ort->dst.dev, 0,
 +                                          ort->rt6i_table);
  
        if (rt) {
                rt->dst.input = ort->dst.input;
@@@ -2029,7 -2099,8 +2029,7 @@@ struct rt6_info *addrconf_dst_alloc(str
                                    bool anycast)
  {
        struct net *net = dev_net(idev->dev);
 -      struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
 -                                          net->loopback_dev, 0);
 +      struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL);
        int err;
  
        if (!rt) {
@@@ -2450,9 -2521,7 +2450,9 @@@ static int rt6_fill_node(struct net *ne
        else
                expires = INT_MAX;
  
 -      peer = rt->rt6i_peer;
 +      peer = NULL;
 +      if (rt6_has_peer(rt))
 +              peer = rt6_peer_ptr(rt);
        ts = tsage = 0;
        if (peer && peer->tcp_ts_stamp) {
                ts = peer->tcp_ts;
@@@ -2929,31 -2998,6 +2929,31 @@@ static struct pernet_operations ip6_rou
        .exit = ip6_route_net_exit,
  };
  
 +static int __net_init ipv6_inetpeer_init(struct net *net)
 +{
 +      struct inet_peer_base *bp = kmalloc(sizeof(*bp), GFP_KERNEL);
 +
 +      if (!bp)
 +              return -ENOMEM;
 +      inet_peer_base_init(bp);
 +      net->ipv6.peers = bp;
 +      return 0;
 +}
 +
 +static void __net_exit ipv6_inetpeer_exit(struct net *net)
 +{
 +      struct inet_peer_base *bp = net->ipv6.peers;
 +
 +      net->ipv6.peers = NULL;
 +      inetpeer_invalidate_tree(bp);
 +      kfree(bp);
 +}
 +
 +static struct pernet_operations ipv6_inetpeer_ops = {
 +      .init   =       ipv6_inetpeer_init,
 +      .exit   =       ipv6_inetpeer_exit,
 +};
 +
  static struct notifier_block ip6_route_dev_notifier = {
        .notifier_call = ip6_route_dev_notify,
        .priority = 0,
@@@ -2974,14 -3018,14 +2974,18 @@@ int __init ip6_route_init(void
        if (ret)
                goto out_kmem_cache;
  
-       ret = register_pernet_subsys(&ip6_route_net_ops);
+       ret = fib6_init();
        if (ret)
                goto out_dst_entries;
  
 -      ret = register_pernet_subsys(&ip6_route_net_ops);
 +      ret = register_pernet_subsys(&ipv6_inetpeer_ops);
        if (ret)
-               goto out_register_subsys;
+               goto out_fib6_init;
++      ret = register_pernet_subsys(&ip6_route_net_ops);
++      if (ret)
++              goto out_register_inetpeer;
 +
        ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
  
        /* Registering of the loopback is done before this portion of code,
        init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
        init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
    #endif
-       ret = fib6_init();
+       ret = fib6_init_late();
        if (ret)
-               goto out_register_inetpeer;
+               goto out_register_subsys;
  
        ret = xfrm6_init();
        if (ret)
-               goto out_fib6_init;
+               goto out_fib6_init_late;
  
        ret = fib6_rules_init();
        if (ret)
@@@ -3024,12 -3068,12 +3028,14 @@@ fib6_rules_init
        fib6_rules_cleanup();
  xfrm6_init:
        xfrm6_fini();
- out_fib6_init:
-       fib6_gc_cleanup();
- out_register_inetpeer:
-       unregister_pernet_subsys(&ipv6_inetpeer_ops);
+ out_fib6_init_late:
+       fib6_cleanup_late();
  out_register_subsys:
        unregister_pernet_subsys(&ip6_route_net_ops);
++out_register_inetpeer:
++      unregister_pernet_subsys(&ipv6_inetpeer_ops);
+ out_fib6_init:
+       fib6_gc_cleanup();
  out_dst_entries:
        dst_entries_destroy(&ip6_dst_blackhole_ops);
  out_kmem_cache:
@@@ -3043,7 -3087,6 +3049,7 @@@ void ip6_route_cleanup(void
        fib6_rules_cleanup();
        xfrm6_fini();
        fib6_gc_cleanup();
 +      unregister_pernet_subsys(&ipv6_inetpeer_ops);
        unregister_pernet_subsys(&ip6_route_net_ops);
        dst_entries_destroy(&ip6_dst_blackhole_ops);
        kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep);