diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c index d637555a833b..e763d723e4cf 100644 --- a/drivers/dma/iovlock.c +++ b/drivers/dma/iovlock.c @@ -143,29 +143,6 @@ void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list) kfree(pinned_list); } -static dma_cookie_t dma_memcpy_to_kernel_iovec(struct dma_chan *chan, struct - iovec *iov, unsigned char *kdata, size_t len) -{ - dma_cookie_t dma_cookie = 0; - - while (len > 0) { - if (iov->iov_len) { - int copy = min_t(unsigned int, iov->iov_len, len); - dma_cookie = dma_async_memcpy_buf_to_buf( - chan, - iov->iov_base, - kdata, - copy); - kdata += copy; - len -= copy; - iov->iov_len -= copy; - iov->iov_base += copy; - } - iov++; - } - - return dma_cookie; -} /* * We have already pinned down the pages we will be using in the iovecs. @@ -187,10 +164,6 @@ dma_cookie_t dma_memcpy_to_iovec(struct dma_chan *chan, struct iovec *iov, if (!chan) return memcpy_toiovec(iov, kdata, len); - /* -> kernel copies (e.g. smbfs) */ - if (!pinned_list) - return dma_memcpy_to_kernel_iovec(chan, iov, kdata, len); - iovec_idx = 0; while (iovec_idx < pinned_list->nr_iovecs) { struct dma_page_list *page_list; diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 6deb20fc7a08..001c66dd3a94 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -2886,7 +2886,6 @@ static const struct ethtool_ops vortex_ethtool_ops = { .set_settings = vortex_set_settings, .get_link = ethtool_op_get_link, .nway_reset = vortex_nway_reset, - .get_perm_addr = ethtool_op_get_perm_addr, }; #ifdef CONFIG_PCI diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index e970e64bf966..a79f28c7a100 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -1578,7 +1578,6 @@ static const struct ethtool_ops cp_ethtool_ops = { .set_wol = cp_set_wol, .get_strings = cp_get_strings, .get_ethtool_stats = cp_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, .get_eeprom_len = cp_get_eeprom_len, .get_eeprom = cp_get_eeprom, .set_eeprom = cp_set_eeprom, diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 327eaa7b4999..f4e4298d24b9 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -2452,7 +2452,6 @@ static const struct ethtool_ops rtl8139_ethtool_ops = { .get_strings = rtl8139_get_strings, .get_stats_count = rtl8139_get_stats_count, .get_ethtool_stats = rtl8139_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f8a602caabcb..81ef81c9a584 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2851,7 +2851,7 @@ config PPPOATM config PPPOL2TP tristate "PPP over L2TP (EXPERIMENTAL)" - depends on EXPERIMENTAL && PPP + depends on EXPERIMENTAL && PPP && INET help Support for PPP-over-L2TP socket family. L2TP is a protocol used by ISPs and enterprises to tunnel PPP traffic over UDP diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index e43e8047b90e..83da1770bafb 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -580,7 +580,6 @@ static const struct ethtool_ops ax_ethtool_ops = { .set_settings = ax_set_settings, .nway_reset = ax_nway_reset, .get_link = ax_get_link, - .get_perm_addr = ethtool_op_get_perm_addr, }; /* setup code */ diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 37f1b6ff5c12..0795df235492 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2033,7 +2033,6 @@ static const struct ethtool_ops b44_ethtool_ops = { .get_strings = b44_get_strings, .get_stats_count = b44_get_stats_count, .get_ethtool_stats = b44_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index a729da061bbb..d53dfc5bbae0 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -6269,7 +6269,6 @@ static const struct ethtool_ops bnx2_ethtool_ops = { .phys_id = bnx2_phys_id, .get_stats_count = bnx2_get_stats_count, .get_ethtool_stats = bnx2_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; /* Called with rtnl_lock */ diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index cb9cb3013f42..070b78d959cc 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -613,38 +613,20 @@ down: static int bond_update_speed_duplex(struct slave *slave) { struct net_device *slave_dev = slave->dev; - static int (* ioctl)(struct net_device *, struct ifreq *, int); - struct ifreq ifr; struct ethtool_cmd etool; + int res; /* Fake speed and duplex */ slave->speed = SPEED_100; slave->duplex = DUPLEX_FULL; - if (slave_dev->ethtool_ops) { - int res; - - if (!slave_dev->ethtool_ops->get_settings) { - return -1; - } - - res = slave_dev->ethtool_ops->get_settings(slave_dev, &etool); - if (res < 0) { - return -1; - } - - goto verify; - } - - ioctl = slave_dev->do_ioctl; - strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ); - etool.cmd = ETHTOOL_GSET; - ifr.ifr_data = (char*)&etool; - if (!ioctl || (IOCTL(slave_dev, &ifr, SIOCETHTOOL) < 0)) { + if (!slave_dev->ethtool_ops || !slave_dev->ethtool_ops->get_settings) + return -1; + + res = slave_dev->ethtool_ops->get_settings(slave_dev, &etool); + if (res < 0) return -1; - } -verify: switch (etool.speed) { case SPEED_10: case SPEED_100: @@ -690,7 +672,6 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de static int (* ioctl)(struct net_device *, struct ifreq *, int); struct ifreq ifr; struct mii_ioctl_data *mii; - struct ethtool_value etool; if (bond->params.use_carrier) { return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0; @@ -721,9 +702,10 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de } } - /* try SIOCETHTOOL ioctl, some drivers cache ETHTOOL_GLINK */ - /* for a period of time so we attempt to get link status */ - /* from it last if the above MII ioctls fail... */ + /* + * Some drivers cache ETHTOOL_GLINK for a period of time so we only + * attempt to get link status from it if the above MII ioctls fail. + */ if (slave_dev->ethtool_ops) { if (slave_dev->ethtool_ops->get_link) { u32 link; @@ -734,23 +716,9 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de } } - if (ioctl) { - strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ); - etool.cmd = ETHTOOL_GLINK; - ifr.ifr_data = (char*)&etool; - if (IOCTL(slave_dev, &ifr, SIOCETHTOOL) == 0) { - if (etool.data == 1) { - return BMSR_LSTATUS; - } else { - dprintk("SIOCETHTOOL shows link down\n"); - return 0; - } - } - } - /* * If reporting, report that either there's no dev->do_ioctl, - * or both SIOCGMIIREG and SIOCETHTOOL failed (meaning that we + * or both SIOCGMIIREG and get_link failed (meaning that we * cannot report link status). If not reporting, pretend * we're ok. */ diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 6fd1e5241833..dc5d26988bb3 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1583,7 +1583,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = { .get_wol = get_wol, .get_tso = ethtool_op_get_tso, .set_tso = ethtool_op_set_tso, - .get_perm_addr = ethtool_op_get_perm_addr }; static int in_range(int val, int lo, int hi) diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 6b6401e9304e..280313b9b069 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2506,7 +2506,6 @@ static const struct ethtool_ops e100_ethtool_ops = { .phys_id = e100_phys_id, .get_stats_count = e100_get_stats_count, .get_ethtool_stats = e100_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index bb08375b5f13..c90c92e72d2a 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -1973,7 +1973,6 @@ static const struct ethtool_ops e1000_ethtool_ops = { .phys_id = e1000_phys_id, .get_stats_count = e1000_get_stats_count, .get_ethtool_stats = e1000_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; void e1000_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 51e1cb472738..69f5f365239a 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -4707,7 +4707,6 @@ static const struct ethtool_ops ops = { .get_regs_len = nv_get_regs_len, .get_regs = nv_get_regs, .nway_reset = nv_nway_reset, - .get_perm_addr = ethtool_op_get_perm_addr, .get_tso = ethtool_op_get_tso, .set_tso = nv_set_tso, .get_ringparam = nv_get_ringparam, diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index afde84868bea..0413cd95eda7 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c @@ -724,7 +724,6 @@ static const struct ethtool_ops ixgb_ethtool_ops = { .phys_id = ixgb_phys_id, .get_stats_count = ixgb_get_stats_count, .get_ethtool_stats = ixgb_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; void ixgb_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 6ba6ed2b480a..5106c2328d12 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -229,7 +229,12 @@ struct net_device loopback_dev = { /* Setup and register the loopback device. */ static int __init loopback_init(void) { - return register_netdev(&loopback_dev); + int err = register_netdev(&loopback_dev); + + if (err) + panic("loopback: Failed to register netdevice: %d\n", err); + + return err; }; module_init(loopback_init); diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index cfdeaf7aa163..f81d9398d605 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -638,7 +638,6 @@ static const struct ethtool_ops ne2k_pci_ethtool_ops = { .get_drvinfo = ne2k_pci_get_drvinfo, .get_tx_csum = ethtool_op_get_tx_csum, .get_sg = ethtool_op_get_sg, - .get_perm_addr = ethtool_op_get_perm_addr, }; static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev) diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 0175f6c353f6..a6138b474b4a 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -755,5 +755,4 @@ struct ethtool_ops netxen_nic_ethtool_ops = { .get_strings = netxen_nic_get_strings, .get_stats_count = netxen_nic_get_stats_count, .get_ethtool_stats = netxen_nic_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 465485a3fbc6..e6a67531de99 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1515,7 +1515,6 @@ static const struct ethtool_ops pcnet32_ethtool_ops = { .phys_id = pcnet32_phys_id, .get_regs_len = pcnet32_get_regs_len, .get_regs = pcnet32_get_regs, - .get_perm_addr = ethtool_op_get_perm_addr, }; /* only probes for non-PCI devices, the rest are handled by diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 6f98834e6ace..68631a5721ac 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -108,19 +108,24 @@ static inline int cmp_addr(struct pppoe_addr *a, unsigned long sid, char *addr) (memcmp(a->remote,addr,ETH_ALEN) == 0)); } -static int hash_item(unsigned long sid, unsigned char *addr) +#if 8%PPPOE_HASH_BITS +#error 8 must be a multiple of PPPOE_HASH_BITS +#endif + +static int hash_item(unsigned int sid, unsigned char *addr) { - char hash = 0; - int i, j; + unsigned char hash = 0; + unsigned int i; - for (i = 0; i < ETH_ALEN ; ++i) { - for (j = 0; j < 8/PPPOE_HASH_BITS ; ++j) { - hash ^= addr[i] >> ( j * PPPOE_HASH_BITS ); - } + for (i = 0 ; i < ETH_ALEN ; i++) { + hash ^= addr[i]; + } + for (i = 0 ; i < sizeof(sid_t)*8 ; i += 8 ){ + hash ^= sid>>i; + } + for (i = 8 ; (i>>=1) >= PPPOE_HASH_BITS ; ) { + hash ^= hash>>i; } - - for (i = 0; i < (sizeof(unsigned long)*8) / PPPOE_HASH_BITS ; ++i) - hash ^= sid >> (i*PPPOE_HASH_BITS); return hash & ( PPPOE_HASH_SIZE - 1 ); } @@ -664,8 +669,8 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd, { struct sock *sk = sock->sk; struct pppox_sock *po = pppox_sk(sk); - int val = 0; - int err = 0; + int val; + int err; switch (cmd) { case PPPIOCGMRU: @@ -754,8 +759,9 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd, err = 0; break; - default:; - }; + default: + err = -ENOTTY; + } return err; } @@ -773,6 +779,7 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, struct net_device *dev; char *start; + lock_sock(sk); if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) { error = -ENOTCONN; goto end; @@ -783,8 +790,6 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, hdr.code = 0; hdr.sid = po->num; - lock_sock(sk); - dev = po->pppoe_dev; error = -EMSGSIZE; diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c index f3e47d0c2b3c..25c52b55c38f 100644 --- a/drivers/net/pppox.c +++ b/drivers/net/pppox.c @@ -73,7 +73,7 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; struct pppox_sock *po = pppox_sk(sk); - int rc = 0; + int rc; lock_sock(sk); @@ -94,12 +94,9 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; } default: - if (pppox_protos[sk->sk_protocol]->ioctl) - rc = pppox_protos[sk->sk_protocol]->ioctl(sock, cmd, - arg); - - break; - }; + rc = pppox_protos[sk->sk_protocol]->ioctl ? + pppox_protos[sk->sk_protocol]->ioctl(sock, cmd, arg) : -ENOTTY; + } release_sock(sk); return rc; diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 8be8be451ada..69da95b5ad0c 100755 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -1904,7 +1904,6 @@ static void ql_get_pauseparam(struct net_device *ndev, static const struct ethtool_ops ql3xxx_ethtool_ops = { .get_settings = ql_get_settings, .get_drvinfo = ql_get_drvinfo, - .get_perm_addr = ethtool_op_get_perm_addr, .get_link = ethtool_op_get_link, .get_msglevel = ql_get_msglevel, .set_msglevel = ql_set_msglevel, diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index bb6896ae3151..c9333b9dd51a 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1066,7 +1066,6 @@ static const struct ethtool_ops rtl8169_ethtool_ops = { .get_strings = rtl8169_get_strings, .get_stats_count = rtl8169_get_stats_count, .get_ethtool_stats = rtl8169_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index 5b7284c955dc..872cb1cc9c41 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c @@ -1402,7 +1402,6 @@ static struct ethtool_ops sc92031_ethtool_ops = { .get_strings = sc92031_ethtool_get_strings, .get_stats_count = sc92031_ethtool_get_stats_count, .get_ethtool_stats = sc92031_ethtool_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, .get_ufo = ethtool_op_get_ufo, }; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 776692946562..e3d8520209b8 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -821,7 +821,6 @@ static const struct ethtool_ops skge_ethtool_ops = { .phys_id = skge_phys_id, .get_stats_count = skge_get_stats_count, .get_ethtool_stats = skge_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; /* diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 13f08a390e1f..e7a2eadcc3b0 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3548,7 +3548,6 @@ static const struct ethtool_ops sky2_ethtool_ops = { .phys_id = sky2_phys_id, .get_stats_count = sky2_get_stats_count, .get_ethtool_stats = sky2_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; #ifdef CONFIG_SKY2_DEBUG diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index af0c9831074c..a8f2af8f778a 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -1586,7 +1586,6 @@ static const struct ethtool_ops ethtool_ops = { .get_link = get_link, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, - .get_perm_addr = ethtool_op_get_perm_addr, }; static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index 61f98251feab..ff1028a597df 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c @@ -906,7 +906,6 @@ static const struct ethtool_ops vnet_ethtool_ops = { .get_msglevel = vnet_get_msglevel, .set_msglevel = vnet_set_msglevel, .get_link = ethtool_op_get_link, - .get_perm_addr = ethtool_op_get_perm_addr, }; static void vnet_port_free_tx_bufs(struct vnet_port *port) diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 7f94ca930988..ec41469eee82 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -2198,7 +2198,6 @@ static const struct ethtool_ops tc35815_ethtool_ops = { .get_strings = tc35815_get_strings, .get_stats_count = tc35815_get_stats_count, .get_ethtool_stats = tc35815_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; static int tc35815_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 887b9a5cfe48..dc41c055ebb5 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9294,7 +9294,6 @@ static const struct ethtool_ops tg3_ethtool_ops = { .get_ethtool_stats = tg3_get_ethtool_stats, .get_coalesce = tg3_get_coalesce, .set_coalesce = tg3_set_coalesce, - .get_perm_addr = ethtool_op_get_perm_addr, }; static void __devinit tg3_get_eeprom_size(struct tg3 *tp) diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index f51c2c138f10..c3fe230695a0 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -1805,7 +1805,6 @@ static const struct ethtool_ops netdev_ethtool_ops = { .set_wol = rhine_set_wol, .get_sg = ethtool_op_get_sg, .get_tx_csum = ethtool_op_get_tx_csum, - .get_perm_addr = ethtool_op_get_perm_addr, }; static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 3a632244f31b..23ccea811297 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -270,8 +270,6 @@ u32 ethtool_op_get_sg(struct net_device *dev); int ethtool_op_set_sg(struct net_device *dev, u32 data); u32 ethtool_op_get_tso(struct net_device *dev); int ethtool_op_set_tso(struct net_device *dev, u32 data); -int ethtool_op_get_perm_addr(struct net_device *dev, - struct ethtool_perm_addr *addr, u8 *data); u32 ethtool_op_get_ufo(struct net_device *dev); int ethtool_op_set_ufo(struct net_device *dev, u32 data); @@ -309,7 +307,6 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data); * get_strings: Return a set of strings that describe the requested objects * phys_id: Identify the device * get_stats: Return statistics about the device - * get_perm_addr: Gets the permanent hardware address * * Description: * @@ -368,7 +365,6 @@ struct ethtool_ops { int (*phys_id)(struct net_device *, u32); int (*get_stats_count)(struct net_device *); void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); - int (*get_perm_addr)(struct net_device *, struct ethtool_perm_addr *, u8 *); int (*begin)(struct net_device *); void (*complete)(struct net_device *); u32 (*get_ufo)(struct net_device *); diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 97983dc9df13..4ca60c3320fb 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -219,7 +219,6 @@ enum { #include #include -#include /* struct ipv6_mc_socklist */ #include static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb) @@ -273,6 +272,10 @@ struct tcp6_request_sock { struct inet6_request_sock tcp6rsk_inet6; }; +struct ipv6_mc_socklist; +struct ipv6_ac_socklist; +struct ipv6_fl_socklist; + /** * struct ipv6_pinfo - ipv6 private area * diff --git a/include/linux/notifier.h b/include/linux/notifier.h index be3f2bb6fcf3..fad7ff17e468 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -157,6 +157,19 @@ extern int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, */ #define NOTIFY_STOP (NOTIFY_OK|NOTIFY_STOP_MASK) +/* Encapsulate (negative) errno value (in particular, NOTIFY_BAD <=> EPERM). */ +static inline int notifier_from_errno(int err) +{ + return NOTIFY_STOP_MASK | (NOTIFY_OK - err); +} + +/* Restore (negative) errno value from notify return value. */ +static inline int notifier_to_errno(int ret) +{ + ret &= ~NOTIFY_STOP_MASK; + return ret > NOTIFY_OK ? NOTIFY_OK - ret : 0; +} + /* * Declared notifiers so far. I can imagine quite a few more chains * over time (eg laptop power reset chains, reboot chain (to clean diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index ce256438e619..93c27f71122a 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -134,8 +134,8 @@ typedef struct skb_frag_struct skb_frag_t; struct skb_frag_struct { struct page *page; - __u16 page_offset; - __u16 size; + __u32 page_offset; + __u32 size; }; /* This data is invariant across clones and lives at diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 6de1e9e35c73..0864a775de24 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -12,37 +12,8 @@ extern void unix_gc(void); #define UNIX_HASH_SIZE 256 -extern struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; -extern spinlock_t unix_table_lock; - extern atomic_t unix_tot_inflight; -static inline struct sock *first_unix_socket(int *i) -{ - for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) { - if (!hlist_empty(&unix_socket_table[*i])) - return __sk_head(&unix_socket_table[*i]); - } - return NULL; -} - -static inline struct sock *next_unix_socket(int *i, struct sock *s) -{ - struct sock *next = sk_next(s); - /* More in this chain? */ - if (next) - return next; - /* Look for next non-empty chain. */ - for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) { - if (!hlist_empty(&unix_socket_table[*i])) - return __sk_head(&unix_socket_table[*i]); - } - return NULL; -} - -#define forall_unix_sockets(i, s) \ - for (s = first_unix_socket(&(i)); s; s = next_unix_socket(&(i),(s))) - struct unix_address { atomic_t refcnt; int len; diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 87df4e87622d..70e70f5d3dd6 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -34,7 +34,7 @@ /* L2CAP socket address */ struct sockaddr_l2 { sa_family_t l2_family; - unsigned short l2_psm; + __le16 l2_psm; bdaddr_t l2_bdaddr; }; @@ -76,32 +76,32 @@ struct l2cap_conninfo { /* L2CAP structures */ struct l2cap_hdr { - __u16 len; - __u16 cid; + __le16 len; + __le16 cid; } __attribute__ ((packed)); #define L2CAP_HDR_SIZE 4 struct l2cap_cmd_hdr { __u8 code; __u8 ident; - __u16 len; + __le16 len; } __attribute__ ((packed)); #define L2CAP_CMD_HDR_SIZE 4 struct l2cap_cmd_rej { - __u16 reason; + __le16 reason; } __attribute__ ((packed)); struct l2cap_conn_req { - __u16 psm; - __u16 scid; + __le16 psm; + __le16 scid; } __attribute__ ((packed)); struct l2cap_conn_rsp { - __u16 dcid; - __u16 scid; - __u16 result; - __u16 status; + __le16 dcid; + __le16 scid; + __le16 result; + __le16 status; } __attribute__ ((packed)); /* connect result */ @@ -117,15 +117,15 @@ struct l2cap_conn_rsp { #define L2CAP_CS_AUTHOR_PEND 0x0002 struct l2cap_conf_req { - __u16 dcid; - __u16 flags; + __le16 dcid; + __le16 flags; __u8 data[0]; } __attribute__ ((packed)); struct l2cap_conf_rsp { - __u16 scid; - __u16 flags; - __u16 result; + __le16 scid; + __le16 flags; + __le16 result; __u8 data[0]; } __attribute__ ((packed)); @@ -149,23 +149,23 @@ struct l2cap_conf_opt { #define L2CAP_CONF_MAX_SIZE 22 struct l2cap_disconn_req { - __u16 dcid; - __u16 scid; + __le16 dcid; + __le16 scid; } __attribute__ ((packed)); struct l2cap_disconn_rsp { - __u16 dcid; - __u16 scid; + __le16 dcid; + __le16 scid; } __attribute__ ((packed)); struct l2cap_info_req { - __u16 type; + __le16 type; __u8 data[0]; } __attribute__ ((packed)); struct l2cap_info_rsp { - __u16 type; - __u16 result; + __le16 type; + __le16 result; __u8 data[0]; } __attribute__ ((packed)); @@ -207,7 +207,7 @@ struct l2cap_conn { struct l2cap_pinfo { struct bt_sock bt; - __u16 psm; + __le16 psm; __u16 dcid; __u16 scid; @@ -225,7 +225,7 @@ struct l2cap_pinfo { __u8 ident; - __u16 sport; + __le16 sport; struct l2cap_conn *conn; struct sock *next_c; diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 46b9dce82f6e..9059e0ed7fe3 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h index 5a8965904377..070d12cb4634 100644 --- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h +++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h @@ -7,9 +7,6 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6; -extern int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start, - u8 *nexthdrp, int len); - extern int nf_ct_frag6_init(void); extern void nf_ct_frag6_cleanup(void); extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb); diff --git a/include/net/tcp.h b/include/net/tcp.h index 8b404b1ef7c8..c209361ab74a 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -660,7 +660,7 @@ struct tcp_congestion_ops { /* new value of cwnd after loss (optional) */ u32 (*undo_cwnd)(struct sock *sk); /* hook for packet ack accounting (optional) */ - void (*pkts_acked)(struct sock *sk, u32 num_acked, ktime_t last); + void (*pkts_acked)(struct sock *sk, u32 num_acked, s32 rtt_us); /* get info for inet_diag (optional) */ void (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb); diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 4d2aa4dd42ac..4bab322c9f8f 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -668,9 +668,6 @@ int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (real_dev->do_ioctl && netif_device_present(real_dev)) err = real_dev->do_ioctl(real_dev, &ifrr, cmd); break; - - case SIOCETHTOOL: - err = dev_ethtool(&ifrr); } if (!err) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 670ff95ca64b..c4e4ce4ebb2b 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -353,7 +353,7 @@ static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 } /* ---- Socket interface ---- */ -static struct sock *__l2cap_get_sock_by_addr(u16 psm, bdaddr_t *src) +static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) { struct sock *sk; struct hlist_node *node; @@ -368,7 +368,7 @@ found: /* Find socket with psm and source bdaddr. * Returns closest match. */ -static struct sock *__l2cap_get_sock_by_psm(int state, u16 psm, bdaddr_t *src) +static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) { struct sock *sk = NULL, *sk1 = NULL; struct hlist_node *node; @@ -392,7 +392,7 @@ static struct sock *__l2cap_get_sock_by_psm(int state, u16 psm, bdaddr_t *src) /* Find socket with given address (psm, src). * Returns locked socket */ -static inline struct sock *l2cap_get_sock_by_psm(int state, u16 psm, bdaddr_t *src) +static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) { struct sock *s; read_lock(&l2cap_sk_list.lock); @@ -586,7 +586,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_ goto done; } - if (la->l2_psm > 0 && btohs(la->l2_psm) < 0x1001 && + if (la->l2_psm && btohs(la->l2_psm) < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) { err = -EACCES; goto done; @@ -748,7 +748,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) write_lock_bh(&l2cap_sk_list.lock); for (psm = 0x1001; psm < 0x1100; psm += 2) - if (!__l2cap_get_sock_by_addr(psm, src)) { + if (!__l2cap_get_sock_by_addr(htobs(psm), src)) { l2cap_pi(sk)->psm = htobs(psm); l2cap_pi(sk)->sport = htobs(psm); err = 0; @@ -873,7 +873,7 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len) lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); if (sk->sk_type == SOCK_DGRAM) - put_unaligned(l2cap_pi(sk)->psm, (u16 *) skb_put(skb, 2)); + put_unaligned(l2cap_pi(sk)->psm, (__le16 *) skb_put(skb, 2)); if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) { err = -EFAULT; @@ -1256,11 +1256,11 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned break; case 2: - *val = __le16_to_cpu(*((u16 *)opt->val)); + *val = __le16_to_cpu(*((__le16 *)opt->val)); break; case 4: - *val = __le32_to_cpu(*((u32 *)opt->val)); + *val = __le32_to_cpu(*((__le32 *)opt->val)); break; default: @@ -1287,11 +1287,11 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) break; case 2: - *((u16 *) opt->val) = cpu_to_le16(val); + *((__le16 *) opt->val) = cpu_to_le16(val); break; case 4: - *((u32 *) opt->val) = cpu_to_le32(val); + *((__le32 *) opt->val) = cpu_to_le32(val); break; default: @@ -1406,7 +1406,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd int result = 0, status = 0; u16 dcid = 0, scid = __le16_to_cpu(req->scid); - u16 psm = req->psm; + __le16 psm = req->psm; BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid); @@ -1530,7 +1530,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd return 0; } -static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) +static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; u16 dcid, flags; @@ -1550,7 +1550,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr goto unlock; /* Reject if config buffer is too small. */ - len = cmd->len - sizeof(*req); + len = cmd_len - sizeof(*req); if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, @@ -1748,15 +1748,16 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk l2cap_raw_recv(conn, skb); while (len >= L2CAP_CMD_HDR_SIZE) { + u16 cmd_len; memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE); data += L2CAP_CMD_HDR_SIZE; len -= L2CAP_CMD_HDR_SIZE; - cmd.len = __le16_to_cpu(cmd.len); + cmd_len = le16_to_cpu(cmd.len); - BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident); + BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident); - if (cmd.len > len || !cmd.ident) { + if (cmd_len > len || !cmd.ident) { BT_DBG("corrupted command"); break; } @@ -1775,7 +1776,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk break; case L2CAP_CONF_REQ: - err = l2cap_config_req(conn, &cmd, data); + err = l2cap_config_req(conn, &cmd, cmd_len, data); break; case L2CAP_CONF_RSP: @@ -1791,7 +1792,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk break; case L2CAP_ECHO_REQ: - l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data); + l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data); break; case L2CAP_ECHO_RSP: @@ -1820,8 +1821,8 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); } - data += cmd.len; - len -= cmd.len; + data += cmd_len; + len -= cmd_len; } kfree_skb(skb); @@ -1863,7 +1864,7 @@ done: return 0; } -static inline int l2cap_conless_channel(struct l2cap_conn *conn, u16 psm, struct sk_buff *skb) +static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb) { struct sock *sk; @@ -1893,7 +1894,8 @@ done: static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) { struct l2cap_hdr *lh = (void *) skb->data; - u16 cid, psm, len; + u16 cid, len; + __le16 psm; skb_pull(skb, L2CAP_HDR_SIZE); cid = __le16_to_cpu(lh->cid); @@ -1907,7 +1909,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) break; case 0x0002: - psm = get_unaligned((u16 *) skb->data); + psm = get_unaligned((__le16 *) skb->data); skb_pull(skb, 2); l2cap_conless_channel(conn, psm, skb); break; diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 23ba61a13bdd..22a832098d44 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -267,7 +267,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) out: write_unlock_bh(&rfcomm_dev_lock); - if (err) { + if (err < 0) { kfree(dev); return err; } @@ -275,9 +275,10 @@ out: dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL); if (IS_ERR(dev->tty_dev)) { + err = PTR_ERR(dev->tty_dev); list_del(&dev->list); kfree(dev); - return PTR_ERR(dev->tty_dev); + return err; } return dev->id; diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 7b4ce9113be2..b40dada002bf 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -29,35 +29,24 @@ * Determine initial path cost based on speed. * using recommendations from 802.1d standard * - * Need to simulate user ioctl because not all device's that support - * ethtool, use ethtool_ops. Also, since driver might sleep need to - * not be holding any locks. + * Since driver might sleep need to not be holding any locks. */ static int port_cost(struct net_device *dev) { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - struct ifreq ifr; - mm_segment_t old_fs; - int err; - - strncpy(ifr.ifr_name, dev->name, IFNAMSIZ); - ifr.ifr_data = (void __user *) &ecmd; - - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = dev_ethtool(&ifr); - set_fs(old_fs); - - if (!err) { - switch(ecmd.speed) { - case SPEED_100: - return 19; - case SPEED_1000: - return 4; - case SPEED_10000: - return 2; - case SPEED_10: - return 100; + if (dev->ethtool_ops->get_settings) { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + int err = dev->ethtool_ops->get_settings(dev, &ecmd); + if (!err) { + switch(ecmd.speed) { + case SPEED_100: + return 19; + case SPEED_1000: + return 4; + case SPEED_10000: + return 2; + case SPEED_10: + return 100; + } } } diff --git a/net/core/dev.c b/net/core/dev.c index ee4035571c21..6cc8a70350ac 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -817,7 +817,9 @@ int dev_alloc_name(struct net_device *dev, const char *name) */ int dev_change_name(struct net_device *dev, char *newname) { + char oldname[IFNAMSIZ]; int err = 0; + int ret; ASSERT_RTNL(); @@ -827,6 +829,8 @@ int dev_change_name(struct net_device *dev, char *newname) if (!dev_valid_name(newname)) return -EINVAL; + memcpy(oldname, dev->name, IFNAMSIZ); + if (strchr(newname, '%')) { err = dev_alloc_name(dev, newname); if (err < 0) @@ -838,10 +842,28 @@ int dev_change_name(struct net_device *dev, char *newname) else strlcpy(dev->name, newname, IFNAMSIZ); +rollback: device_rename(&dev->dev, dev->name); + + write_lock_bh(&dev_base_lock); hlist_del(&dev->name_hlist); hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); - raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); + write_unlock_bh(&dev_base_lock); + + ret = raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); + ret = notifier_to_errno(ret); + + if (ret) { + if (err) { + printk(KERN_ERR + "%s: name change rollback failed: %d.\n", + dev->name, ret); + } else { + err = ret; + memcpy(dev->name, oldname, IFNAMSIZ); + goto rollback; + } + } return err; } @@ -1054,20 +1076,43 @@ int dev_close(struct net_device *dev) int register_netdevice_notifier(struct notifier_block *nb) { struct net_device *dev; + struct net_device *last; int err; rtnl_lock(); err = raw_notifier_chain_register(&netdev_chain, nb); - if (!err) { - for_each_netdev(dev) { - nb->notifier_call(nb, NETDEV_REGISTER, dev); + if (err) + goto unlock; - if (dev->flags & IFF_UP) - nb->notifier_call(nb, NETDEV_UP, dev); - } + for_each_netdev(dev) { + err = nb->notifier_call(nb, NETDEV_REGISTER, dev); + err = notifier_to_errno(err); + if (err) + goto rollback; + + if (!(dev->flags & IFF_UP)) + continue; + + nb->notifier_call(nb, NETDEV_UP, dev); } + +unlock: rtnl_unlock(); return err; + +rollback: + last = dev; + for_each_netdev(dev) { + if (dev == last) + break; + + if (dev->flags & IFF_UP) { + nb->notifier_call(nb, NETDEV_GOING_DOWN, dev); + nb->notifier_call(nb, NETDEV_DOWN, dev); + } + nb->notifier_call(nb, NETDEV_UNREGISTER, dev); + } + goto unlock; } /** @@ -2718,9 +2763,11 @@ int __dev_addr_add(struct dev_addr_list **list, int *count, /** * dev_unicast_delete - Release secondary unicast address. * @dev: device + * @addr: address to delete + * @alen: length of @addr * * Release reference to a secondary unicast address and remove it - * from the device if the reference count drop to zero. + * from the device if the reference count drops to zero. * * The caller must hold the rtnl_mutex. */ @@ -2742,6 +2789,8 @@ EXPORT_SYMBOL(dev_unicast_delete); /** * dev_unicast_add - add a secondary unicast address * @dev: device + * @addr: address to delete + * @alen: length of @addr * * Add a secondary unicast address to the device or increase * the reference count if it already exists. @@ -3333,7 +3382,7 @@ int register_netdevice(struct net_device *dev) if (!dev_valid_name(dev->name)) { ret = -EINVAL; - goto out; + goto err_uninit; } dev->ifindex = dev_new_index(); @@ -3347,7 +3396,7 @@ int register_netdevice(struct net_device *dev) = hlist_entry(p, struct net_device, name_hlist); if (!strncmp(d->name, dev->name, IFNAMSIZ)) { ret = -EEXIST; - goto out; + goto err_uninit; } } @@ -3407,7 +3456,7 @@ int register_netdevice(struct net_device *dev) ret = netdev_register_sysfs(dev); if (ret) - goto out; + goto err_uninit; dev->reg_state = NETREG_REGISTERED; /* @@ -3426,12 +3475,18 @@ int register_netdevice(struct net_device *dev) write_unlock_bh(&dev_base_lock); /* Notify protocols, that a new device appeared. */ - raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); - - ret = 0; + ret = raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); + ret = notifier_to_errno(ret); + if (ret) + unregister_netdevice(dev); out: return ret; + +err_uninit: + if (dev->uninit) + dev->uninit(dev); + goto out; } /** @@ -3830,9 +3885,11 @@ static int dev_cpu_callback(struct notifier_block *nfb, #ifdef CONFIG_NET_DMA /** - * net_dma_rebalance - - * This is called when the number of channels allocated to the net_dma_client - * changes. The net_dma_client tries to have one DMA channel per CPU. + * net_dma_rebalance - try to maintain one DMA channel per CPU + * @net_dma: DMA client and associated data (lock, channels, channel_mask) + * + * This is called when the number of channels allocated to the net_dma client + * changes. The net_dma client tries to have one DMA channel per CPU. */ static void net_dma_rebalance(struct net_dma *net_dma) @@ -3869,7 +3926,7 @@ static void net_dma_rebalance(struct net_dma *net_dma) * netdev_dma_event - event callback for the net_dma_client * @client: should always be net_dma_client * @chan: DMA channel for the event - * @event: event type + * @state: DMA state to be handled */ static enum dma_state_client netdev_dma_event(struct dma_client *client, struct dma_chan *chan, diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 0b531e98ec33..2ab0a60046a5 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -3,10 +3,12 @@ * Copyright (c) 2003 Matthew Wilcox * * This file is where we call all the ethtool_ops commands to get - * the information ethtool needs. We fall back to calling do_ioctl() - * for drivers which haven't been converted to ethtool_ops yet. + * the information ethtool needs. * - * It's GPL, stupid. + * 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. */ #include @@ -93,18 +95,6 @@ int ethtool_op_set_tso(struct net_device *dev, u32 data) return 0; } -int ethtool_op_get_perm_addr(struct net_device *dev, struct ethtool_perm_addr *addr, u8 *data) -{ - unsigned char len = dev->addr_len; - if ( addr->size < len ) - return -ETOOSMALL; - - addr->size = len; - memcpy(data, dev->perm_addr, len); - return 0; -} - - u32 ethtool_op_get_ufo(struct net_device *dev) { return (dev->features & NETIF_F_UFO) != 0; @@ -777,34 +767,20 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr) { struct ethtool_perm_addr epaddr; - u8 *data; - int ret; - if (!dev->ethtool_ops->get_perm_addr) - return -EOPNOTSUPP; - - if (copy_from_user(&epaddr,useraddr,sizeof(epaddr))) + if (copy_from_user(&epaddr, useraddr, sizeof(epaddr))) return -EFAULT; - data = kmalloc(epaddr.size, GFP_USER); - if (!data) - return -ENOMEM; + if (epaddr.size < dev->addr_len) + return -ETOOSMALL; + epaddr.size = dev->addr_len; - ret = dev->ethtool_ops->get_perm_addr(dev,&epaddr,data); - if (ret) - return ret; - - ret = -EFAULT; if (copy_to_user(useraddr, &epaddr, sizeof(epaddr))) - goto out; + return -EFAULT; useraddr += sizeof(epaddr); - if (copy_to_user(useraddr, data, epaddr.size)) - goto out; - ret = 0; - - out: - kfree(data); - return ret; + if (copy_to_user(useraddr, dev->perm_addr, epaddr.size)) + return -EFAULT; + return 0; } /* The main entry point in this file. Called from net/core/dev.c */ @@ -821,7 +797,7 @@ int dev_ethtool(struct ifreq *ifr) return -ENODEV; if (!dev->ethtool_ops) - goto ioctl; + return -EOPNOTSUPP; if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) return -EFAULT; @@ -960,7 +936,7 @@ int dev_ethtool(struct ifreq *ifr) rc = ethtool_set_gso(dev, useraddr); break; default: - rc = -EOPNOTSUPP; + rc = -EOPNOTSUPP; } if (dev->ethtool_ops->complete) @@ -970,20 +946,10 @@ int dev_ethtool(struct ifreq *ifr) netdev_features_change(dev); return rc; - - ioctl: - /* Keep existing behaviour for the moment. */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - if (dev->do_ioctl) - return dev->do_ioctl(dev, ifr, SIOCETHTOOL); - return -EOPNOTSUPP; } EXPORT_SYMBOL(dev_ethtool); EXPORT_SYMBOL(ethtool_op_get_link); -EXPORT_SYMBOL_GPL(ethtool_op_get_perm_addr); EXPORT_SYMBOL(ethtool_op_get_sg); EXPORT_SYMBOL(ethtool_op_get_tso); EXPORT_SYMBOL(ethtool_op_get_tx_csum); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index bca787fdbc51..7bae576ac115 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -567,7 +567,7 @@ static ssize_t pgctrl_write(struct file *file, const char __user * buf, pktgen_run_all_threads(); else - printk("pktgen: Unknown command: %s\n", data); + printk(KERN_WARNING "pktgen: Unknown command: %s\n", data); err = count; @@ -908,14 +908,14 @@ static ssize_t pktgen_if_write(struct file *file, pg_result = &(pkt_dev->result[0]); if (count < 1) { - printk("pktgen: wrong command format\n"); + printk(KERN_WARNING "pktgen: wrong command format\n"); return -EINVAL; } max = count - i; tmp = count_trail_chars(&user_buffer[i], max); if (tmp < 0) { - printk("pktgen: illegal format\n"); + printk(KERN_WARNING "pktgen: illegal format\n"); return tmp; } i += tmp; @@ -943,7 +943,7 @@ static ssize_t pktgen_if_write(struct file *file, if (copy_from_user(tb, user_buffer, count)) return -EFAULT; tb[count] = 0; - printk("pktgen: %s,%lu buffer -:%s:-\n", name, + printk(KERN_DEBUG "pktgen: %s,%lu buffer -:%s:-\n", name, (unsigned long)count, tb); } @@ -1248,7 +1248,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_daddr = pkt_dev->daddr_min; } if (debug) - printk("pktgen: dst_min set to: %s\n", + printk(KERN_DEBUG "pktgen: dst_min set to: %s\n", pkt_dev->dst_min); i += len; sprintf(pg_result, "OK: dst_min=%s", pkt_dev->dst_min); @@ -1271,7 +1271,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_daddr = pkt_dev->daddr_max; } if (debug) - printk("pktgen: dst_max set to: %s\n", + printk(KERN_DEBUG "pktgen: dst_max set to: %s\n", pkt_dev->dst_max); i += len; sprintf(pg_result, "OK: dst_max=%s", pkt_dev->dst_max); @@ -1294,7 +1294,7 @@ static ssize_t pktgen_if_write(struct file *file, ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->in6_daddr); if (debug) - printk("pktgen: dst6 set to: %s\n", buf); + printk(KERN_DEBUG "pktgen: dst6 set to: %s\n", buf); i += len; sprintf(pg_result, "OK: dst6=%s", buf); @@ -1317,7 +1317,7 @@ static ssize_t pktgen_if_write(struct file *file, ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->min_in6_daddr); if (debug) - printk("pktgen: dst6_min set to: %s\n", buf); + printk(KERN_DEBUG "pktgen: dst6_min set to: %s\n", buf); i += len; sprintf(pg_result, "OK: dst6_min=%s", buf); @@ -1338,7 +1338,7 @@ static ssize_t pktgen_if_write(struct file *file, fmt_ip6(buf, pkt_dev->max_in6_daddr.s6_addr); if (debug) - printk("pktgen: dst6_max set to: %s\n", buf); + printk(KERN_DEBUG "pktgen: dst6_max set to: %s\n", buf); i += len; sprintf(pg_result, "OK: dst6_max=%s", buf); @@ -1361,7 +1361,7 @@ static ssize_t pktgen_if_write(struct file *file, ipv6_addr_copy(&pkt_dev->cur_in6_saddr, &pkt_dev->in6_saddr); if (debug) - printk("pktgen: src6 set to: %s\n", buf); + printk(KERN_DEBUG "pktgen: src6 set to: %s\n", buf); i += len; sprintf(pg_result, "OK: src6=%s", buf); @@ -1382,7 +1382,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_saddr = pkt_dev->saddr_min; } if (debug) - printk("pktgen: src_min set to: %s\n", + printk(KERN_DEBUG "pktgen: src_min set to: %s\n", pkt_dev->src_min); i += len; sprintf(pg_result, "OK: src_min=%s", pkt_dev->src_min); @@ -1403,7 +1403,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->cur_saddr = pkt_dev->saddr_max; } if (debug) - printk("pktgen: src_max set to: %s\n", + printk(KERN_DEBUG "pktgen: src_max set to: %s\n", pkt_dev->src_max); i += len; sprintf(pg_result, "OK: src_max=%s", pkt_dev->src_max); @@ -1533,7 +1533,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->svlan_id = 0xffff; if (debug) - printk("pktgen: VLAN/SVLAN auto turned off\n"); + printk(KERN_DEBUG "pktgen: VLAN/SVLAN auto turned off\n"); } return count; } @@ -1548,10 +1548,10 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->vlan_id = value; /* turn on VLAN */ if (debug) - printk("pktgen: VLAN turned on\n"); + printk(KERN_DEBUG "pktgen: VLAN turned on\n"); if (debug && pkt_dev->nr_labels) - printk("pktgen: MPLS auto turned off\n"); + printk(KERN_DEBUG "pktgen: MPLS auto turned off\n"); pkt_dev->nr_labels = 0; /* turn off MPLS */ sprintf(pg_result, "OK: vlan_id=%u", pkt_dev->vlan_id); @@ -1560,7 +1560,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->svlan_id = 0xffff; if (debug) - printk("pktgen: VLAN/SVLAN turned off\n"); + printk(KERN_DEBUG "pktgen: VLAN/SVLAN turned off\n"); } return count; } @@ -1605,10 +1605,10 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->svlan_id = value; /* turn on SVLAN */ if (debug) - printk("pktgen: SVLAN turned on\n"); + printk(KERN_DEBUG "pktgen: SVLAN turned on\n"); if (debug && pkt_dev->nr_labels) - printk("pktgen: MPLS auto turned off\n"); + printk(KERN_DEBUG "pktgen: MPLS auto turned off\n"); pkt_dev->nr_labels = 0; /* turn off MPLS */ sprintf(pg_result, "OK: svlan_id=%u", pkt_dev->svlan_id); @@ -1617,7 +1617,7 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->svlan_id = 0xffff; if (debug) - printk("pktgen: VLAN/SVLAN turned off\n"); + printk(KERN_DEBUG "pktgen: VLAN/SVLAN turned off\n"); } return count; } @@ -1777,10 +1777,11 @@ static ssize_t pktgen_thread_write(struct file *file, i += len; if (debug) - printk("pktgen: t=%s, count=%lu\n", name, (unsigned long)count); + printk(KERN_DEBUG "pktgen: t=%s, count=%lu\n", + name, (unsigned long)count); if (!t) { - printk("pktgen: ERROR: No thread\n"); + printk(KERN_ERR "pktgen: ERROR: No thread\n"); ret = -EINVAL; goto out; } @@ -1891,8 +1892,8 @@ static void pktgen_mark_device(const char *ifname) mutex_lock(&pktgen_thread_lock); if (++i >= max_tries) { - printk("pktgen_mark_device: timed out after waiting " - "%d msec for device %s to be removed\n", + printk(KERN_ERR "pktgen_mark_device: timed out after " + "waiting %d msec for device %s to be removed\n", msec_per_try * i, ifname); break; } @@ -1962,15 +1963,15 @@ static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname) odev = dev_get_by_name(ifname); if (!odev) { - printk("pktgen: no such netdevice: \"%s\"\n", ifname); + printk(KERN_ERR "pktgen: no such netdevice: \"%s\"\n", ifname); return -ENODEV; } if (odev->type != ARPHRD_ETHER) { - printk("pktgen: not an ethernet device: \"%s\"\n", ifname); + printk(KERN_ERR "pktgen: not an ethernet device: \"%s\"\n", ifname); err = -EINVAL; } else if (!netif_running(odev)) { - printk("pktgen: device is down: \"%s\"\n", ifname); + printk(KERN_ERR "pktgen: device is down: \"%s\"\n", ifname); err = -ENETDOWN; } else { pkt_dev->odev = odev; @@ -1987,7 +1988,8 @@ static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname) static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) { if (!pkt_dev->odev) { - printk("pktgen: ERROR: pkt_dev->odev == NULL in setup_inject.\n"); + printk(KERN_ERR "pktgen: ERROR: pkt_dev->odev == NULL in " + "setup_inject.\n"); sprintf(pkt_dev->result, "ERROR: pkt_dev->odev == NULL in setup_inject.\n"); return; @@ -2049,7 +2051,8 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) } rcu_read_unlock(); if (err) - printk("pktgen: ERROR: IPv6 link address not availble.\n"); + printk(KERN_ERR "pktgen: ERROR: IPv6 link " + "address not availble.\n"); } #endif } else { @@ -2156,8 +2159,7 @@ static inline int f_pick(struct pktgen_dev *pkt_dev) /* If there was already an IPSEC SA, we keep it as is, else * we go look for it ... */ -inline -void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow) +static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow) { struct xfrm_state *x = pkt_dev->flows[flow].x; if (!x) { @@ -2441,7 +2443,8 @@ static inline int process_ipsec(struct pktgen_dev *pkt_dev, if (nhead >0) { ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); if (ret < 0) { - printk("Error expanding ipsec packet %d\n",ret); + printk(KERN_ERR "Error expanding " + "ipsec packet %d\n",ret); return 0; } } @@ -2450,7 +2453,8 @@ static inline int process_ipsec(struct pktgen_dev *pkt_dev, skb_pull(skb, ETH_HLEN); ret = pktgen_output_ipsec(skb, pkt_dev); if (ret) { - printk("Error creating ipsec packet %d\n",ret); + printk(KERN_ERR "Error creating ipsec " + "packet %d\n",ret); kfree_skb(skb); return 0; } @@ -3184,8 +3188,8 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev) int nr_frags = pkt_dev->skb ? skb_shinfo(pkt_dev->skb)->nr_frags : -1; if (!pkt_dev->running) { - printk("pktgen: interface: %s is already stopped\n", - pkt_dev->odev->name); + printk(KERN_WARNING "pktgen: interface: %s is already " + "stopped\n", pkt_dev->odev->name); return -EINVAL; } @@ -3360,7 +3364,8 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev) pkt_dev->skb = fill_packet(odev, pkt_dev); if (pkt_dev->skb == NULL) { - printk("pktgen: ERROR: couldn't allocate skb in fill_packet.\n"); + printk(KERN_ERR "pktgen: ERROR: couldn't " + "allocate skb in fill_packet.\n"); schedule(); pkt_dev->clone_count--; /* back out increment, OOM */ goto out; @@ -3565,7 +3570,8 @@ static int add_dev_to_thread(struct pktgen_thread *t, if_lock(t); if (pkt_dev->pg_thread) { - printk("pktgen: ERROR: already assigned to a thread.\n"); + printk(KERN_ERR "pktgen: ERROR: already assigned " + "to a thread.\n"); rv = -EBUSY; goto out; } @@ -3590,7 +3596,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) pkt_dev = __pktgen_NN_threads(ifname, FIND); if (pkt_dev) { - printk("pktgen: ERROR: interface already used.\n"); + printk(KERN_ERR "pktgen: ERROR: interface already used.\n"); return -EBUSY; } @@ -3632,7 +3638,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) pkt_dev->entry = create_proc_entry(ifname, 0600, pg_proc_dir); if (!pkt_dev->entry) { - printk("pktgen: cannot create %s/%s procfs entry.\n", + printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n", PG_PROC_DIR, ifname); err = -EINVAL; goto out2; @@ -3665,7 +3671,8 @@ static int __init pktgen_create_thread(int cpu) t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL); if (!t) { - printk("pktgen: ERROR: out of memory, can't create new thread.\n"); + printk(KERN_ERR "pktgen: ERROR: out of memory, can't " + "create new thread.\n"); return -ENOMEM; } @@ -3678,7 +3685,8 @@ static int __init pktgen_create_thread(int cpu) p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu); if (IS_ERR(p)) { - printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu); + printk(KERN_ERR "pktgen: kernel_thread() failed " + "for cpu %d\n", t->cpu); list_del(&t->th_list); kfree(t); return PTR_ERR(p); @@ -3688,7 +3696,7 @@ static int __init pktgen_create_thread(int cpu) pe = create_proc_entry(t->tsk->comm, 0600, pg_proc_dir); if (!pe) { - printk("pktgen: cannot create %s/%s procfs entry.\n", + printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n", PG_PROC_DIR, t->tsk->comm); kthread_stop(p); list_del(&t->th_list); @@ -3727,7 +3735,8 @@ static int pktgen_remove_device(struct pktgen_thread *t, pr_debug("pktgen: remove_device pkt_dev=%p\n", pkt_dev); if (pkt_dev->running) { - printk("pktgen:WARNING: trying to remove a running interface, stopping it now.\n"); + printk(KERN_WARNING "pktgen: WARNING: trying to remove a " + "running interface, stopping it now.\n"); pktgen_stop_device(pkt_dev); } @@ -3759,7 +3768,7 @@ static int __init pg_init(void) int cpu; struct proc_dir_entry *pe; - printk(version); + printk(KERN_INFO "%s", version); pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net); if (!pg_proc_dir) @@ -3768,8 +3777,8 @@ static int __init pg_init(void) pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir); if (pe == NULL) { - printk("pktgen: ERROR: cannot create %s procfs entry.\n", - PGCTRL); + printk(KERN_ERR "pktgen: ERROR: cannot create %s " + "procfs entry.\n", PGCTRL); proc_net_remove(PG_PROC_DIR); return -EINVAL; } @@ -3785,12 +3794,13 @@ static int __init pg_init(void) err = pktgen_create_thread(cpu); if (err) - printk("pktgen: WARNING: Cannot create thread for cpu %d (%d)\n", - cpu, err); + printk(KERN_WARNING "pktgen: WARNING: Cannot create " + "thread for cpu %d (%d)\n", cpu, err); } if (list_empty(&pktgen_threads)) { - printk("pktgen: ERROR: Initialization failed for all threads\n"); + printk(KERN_ERR "pktgen: ERROR: Initialization failed for " + "all threads\n"); unregister_netdevice_notifier(&pktgen_notifier_block); remove_proc_entry(PGCTRL, pg_proc_dir); proc_net_remove(PG_PROC_DIR); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 06eccca8cb5d..4756d5857abf 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -952,7 +952,9 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct nlattr *linkinfo[IFLA_INFO_MAX+1]; int err; +#ifdef CONFIG_KMOD replay: +#endif err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); if (err < 0) return err; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index f2a61ef2af9c..a4a620971ef0 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1737,8 +1737,9 @@ static int dn_rt_cache_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct dn_rt_cache_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct dn_rt_cache_iter_state *s; + s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; rc = seq_open(file, &dn_rt_cache_seq_ops); @@ -1746,7 +1747,6 @@ static int dn_rt_cache_seq_open(struct inode *inode, struct file *file) goto out_kfree; seq = file->private_data; seq->private = s; - memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index abf6352f990f..5b77bdaa57dd 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1056,10 +1056,9 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, if (!in_dev) { if (event == NETDEV_REGISTER) { in_dev = inetdev_init(dev); + if (!in_dev) + return notifier_from_errno(-ENOMEM); if (dev == &loopback_dev) { - if (!in_dev) - panic("devinet: " - "Failed to create loopback\n"); IN_DEV_CONF_SET(in_dev, NOXFRM, 1); IN_DEV_CONF_SET(in_dev, NOPOLICY, 1); } diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 251346828cb4..2f14745a9e1f 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -513,11 +513,8 @@ void ip_options_undo(struct ip_options * opt) static struct ip_options *ip_options_get_alloc(const int optlen) { - struct ip_options *opt = kmalloc(sizeof(*opt) + ((optlen + 3) & ~3), - GFP_KERNEL); - if (opt) - memset(opt, 0, sizeof(*opt)); - return opt; + return kzalloc(sizeof(struct ip_options) + ((optlen + 3) & ~3), + GFP_KERNEL); } static int ip_options_get_finish(struct ip_options **optp, diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c index 900ce29db382..666e080a74a3 100644 --- a/net/ipv4/ipvs/ip_vs_xmit.c +++ b/net/ipv4/ipvs/ip_vs_xmit.c @@ -128,7 +128,7 @@ ip_vs_dst_reset(struct ip_vs_dest *dest) #define IP_VS_XMIT(skb, rt) \ do { \ (skb)->ipvs_property = 1; \ - (skb)->ip_summed = CHECKSUM_NONE; \ + skb_forward_csum(skb); \ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, (skb), NULL, \ (rt)->u.dst.dev, dst_output); \ } while (0) diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c index 519de091a94d..4586211e3757 100644 --- a/net/ipv4/tcp_bic.c +++ b/net/ipv4/tcp_bic.c @@ -206,7 +206,7 @@ static void bictcp_state(struct sock *sk, u8 new_state) /* Track delayed acknowledgment ratio using sliding window * ratio = (15*ratio + sample) / 16 */ -static void bictcp_acked(struct sock *sk, u32 cnt, ktime_t last) +static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt) { const struct inet_connection_sock *icsk = inet_csk(sk); diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index d17da30d82d6..485d7ea35f75 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c @@ -246,38 +246,12 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd) ca->cnt = 1; } - -/* Keep track of minimum rtt */ -static inline void measure_delay(struct sock *sk) -{ - const struct tcp_sock *tp = tcp_sk(sk); - struct bictcp *ca = inet_csk_ca(sk); - u32 delay; - - /* No time stamp */ - if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) || - /* Discard delay samples right after fast recovery */ - (s32)(tcp_time_stamp - ca->epoch_start) < HZ) - return; - - delay = (tcp_time_stamp - tp->rx_opt.rcv_tsecr)<<3; - if (delay == 0) - delay = 1; - - /* first time call or link delay decreases */ - if (ca->delay_min == 0 || ca->delay_min > delay) - ca->delay_min = delay; -} - static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight, int data_acked) { struct tcp_sock *tp = tcp_sk(sk); struct bictcp *ca = inet_csk_ca(sk); - if (data_acked) - measure_delay(sk); - if (!tcp_is_cwnd_limited(sk, in_flight)) return; @@ -334,17 +308,33 @@ static void bictcp_state(struct sock *sk, u8 new_state) /* Track delayed acknowledgment ratio using sliding window * ratio = (15*ratio + sample) / 16 */ -static void bictcp_acked(struct sock *sk, u32 cnt, ktime_t last) +static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us) { const struct inet_connection_sock *icsk = inet_csk(sk); + struct bictcp *ca = inet_csk_ca(sk); + u32 delay; if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) { - struct bictcp *ca = inet_csk_ca(sk); cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT; ca->delayed_ack += cnt; } -} + /* Some calls are for duplicates without timetamps */ + if (rtt_us < 0) + return; + + /* Discard delay samples right after fast recovery */ + if ((s32)(tcp_time_stamp - ca->epoch_start) < HZ) + return; + + delay = usecs_to_jiffies(rtt_us) << 3; + if (delay == 0) + delay = 1; + + /* first time call or link delay decreases */ + if (ca->delay_min == 0 || ca->delay_min > delay) + ca->delay_min = delay; +} static struct tcp_congestion_ops cubictcp = { .init = bictcp_init, diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c index 08a02e6045c9..b66556c0a5bd 100644 --- a/net/ipv4/tcp_htcp.c +++ b/net/ipv4/tcp_htcp.c @@ -76,12 +76,11 @@ static u32 htcp_cwnd_undo(struct sock *sk) return max(tp->snd_cwnd, (tp->snd_ssthresh << 7) / ca->beta); } -static inline void measure_rtt(struct sock *sk) +static inline void measure_rtt(struct sock *sk, u32 srtt) { const struct inet_connection_sock *icsk = inet_csk(sk); const struct tcp_sock *tp = tcp_sk(sk); struct htcp *ca = inet_csk_ca(sk); - u32 srtt = tp->srtt >> 3; /* keep track of minimum RTT seen so far, minRTT is zero at first */ if (ca->minRTT > srtt || !ca->minRTT) @@ -98,7 +97,7 @@ static inline void measure_rtt(struct sock *sk) } } -static void measure_achieved_throughput(struct sock *sk, u32 pkts_acked, ktime_t last) +static void measure_achieved_throughput(struct sock *sk, u32 pkts_acked, s32 rtt) { const struct inet_connection_sock *icsk = inet_csk(sk); const struct tcp_sock *tp = tcp_sk(sk); @@ -108,6 +107,9 @@ static void measure_achieved_throughput(struct sock *sk, u32 pkts_acked, ktime_t if (icsk->icsk_ca_state == TCP_CA_Open) ca->pkts_acked = pkts_acked; + if (rtt > 0) + measure_rtt(sk, usecs_to_jiffies(rtt)); + if (!use_bandwidth_switch) return; @@ -237,8 +239,6 @@ static void htcp_cong_avoid(struct sock *sk, u32 ack, if (tp->snd_cwnd <= tp->snd_ssthresh) tcp_slow_start(tp); else { - measure_rtt(sk); - /* In dangerous area, increase slowly. * In theory this is tp->snd_cwnd += alpha / tp->snd_cwnd */ diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c index cc5de6f69d46..64f1cbaf96e8 100644 --- a/net/ipv4/tcp_illinois.c +++ b/net/ipv4/tcp_illinois.c @@ -83,18 +83,16 @@ static void tcp_illinois_init(struct sock *sk) } /* Measure RTT for each ack. */ -static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, ktime_t last) +static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, s32 rtt) { struct illinois *ca = inet_csk_ca(sk); - u32 rtt; ca->acked = pkts_acked; - if (ktime_equal(last, net_invalid_timestamp())) + /* dup ack, no rtt sample */ + if (rtt < 0) return; - rtt = ktime_to_us(net_timedelta(last)); - /* ignore bogus values, this prevents wraparound in alpha math */ if (rtt > RTT_MAX) rtt = RTT_MAX; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index fec8a7a4dbaf..378ca8a086a3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1851,19 +1851,22 @@ static inline u32 tcp_cwnd_min(const struct sock *sk) } /* Decrease cwnd each second ack. */ -static void tcp_cwnd_down(struct sock *sk) +static void tcp_cwnd_down(struct sock *sk, int flag) { struct tcp_sock *tp = tcp_sk(sk); int decr = tp->snd_cwnd_cnt + 1; - tp->snd_cwnd_cnt = decr&1; - decr >>= 1; + if ((flag&FLAG_FORWARD_PROGRESS) || + (IsReno(tp) && !(flag&FLAG_NOT_DUP))) { + tp->snd_cwnd_cnt = decr&1; + decr >>= 1; - if (decr && tp->snd_cwnd > tcp_cwnd_min(sk)) - tp->snd_cwnd -= decr; + if (decr && tp->snd_cwnd > tcp_cwnd_min(sk)) + tp->snd_cwnd -= decr; - tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1); - tp->snd_cwnd_stamp = tcp_time_stamp; + tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1); + tp->snd_cwnd_stamp = tcp_time_stamp; + } } /* Nothing was retransmitted or returned timestamp is less @@ -2060,7 +2063,7 @@ static void tcp_try_to_open(struct sock *sk, int flag) } tcp_moderate_cwnd(tp); } else { - tcp_cwnd_down(sk); + tcp_cwnd_down(sk, flag); } } @@ -2109,7 +2112,10 @@ tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una, { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); - int is_dupack = (tp->snd_una == prior_snd_una && !(flag&FLAG_NOT_DUP)); + int is_dupack = (tp->snd_una == prior_snd_una && + (!(flag&FLAG_NOT_DUP) || + ((flag&FLAG_DATA_SACKED) && + (tp->fackets_out > tp->reordering)))); /* Some technical things: * 1. Reno does not count dupacks (sacked_out) automatically. */ @@ -2260,7 +2266,7 @@ tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una, if (is_dupack || tcp_head_timedout(sk)) tcp_update_scoreboard(sk); - tcp_cwnd_down(sk); + tcp_cwnd_down(sk, flag); tcp_xmit_retransmit_queue(sk); } @@ -2490,12 +2496,23 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) tcp_ack_update_rtt(sk, acked, seq_rtt); tcp_ack_packets_out(sk); - /* Is the ACK triggering packet unambiguous? */ - if (acked & FLAG_RETRANS_DATA_ACKED) - last_ackt = net_invalid_timestamp(); + if (ca_ops->pkts_acked) { + s32 rtt_us = -1; - if (ca_ops->pkts_acked) - ca_ops->pkts_acked(sk, pkts_acked, last_ackt); + /* Is the ACK triggering packet unambiguous? */ + if (!(acked & FLAG_RETRANS_DATA_ACKED)) { + /* High resolution needed and available? */ + if (ca_ops->flags & TCP_CONG_RTT_STAMP && + !ktime_equal(last_ackt, + net_invalid_timestamp())) + rtt_us = ktime_us_delta(ktime_get_real(), + last_ackt); + else if (seq_rtt > 0) + rtt_us = jiffies_to_usecs(seq_rtt); + } + + ca_ops->pkts_acked(sk, pkts_acked, rtt_us); + } } #if FASTRETRANS_DEBUG > 0 diff --git a/net/ipv4/tcp_lp.c b/net/ipv4/tcp_lp.c index 80e140e3ec2d..e7f5ef92cbd8 100644 --- a/net/ipv4/tcp_lp.c +++ b/net/ipv4/tcp_lp.c @@ -260,13 +260,13 @@ static void tcp_lp_rtt_sample(struct sock *sk, u32 rtt) * newReno in increase case. * We work it out by following the idea from TCP-LP's paper directly */ -static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, ktime_t last) +static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, s32 rtt_us) { struct tcp_sock *tp = tcp_sk(sk); struct lp *lp = inet_csk_ca(sk); - if (!ktime_equal(last, net_invalid_timestamp())) - tcp_lp_rtt_sample(sk, ktime_to_us(net_timedelta(last))); + if (rtt_us > 0) + tcp_lp_rtt_sample(sk, rtt_us); /* calc inference */ if (tcp_time_stamp > tp->rx_opt.rcv_tsecr) diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c index 914e0307f7af..b49dedcda52d 100644 --- a/net/ipv4/tcp_vegas.c +++ b/net/ipv4/tcp_vegas.c @@ -112,16 +112,16 @@ EXPORT_SYMBOL_GPL(tcp_vegas_init); * o min-filter RTT samples from a much longer window (forever for now) * to find the propagation delay (baseRTT) */ -void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) +void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us) { struct vegas *vegas = inet_csk_ca(sk); u32 vrtt; - if (ktime_equal(last, net_invalid_timestamp())) + if (rtt_us < 0) return; /* Never allow zero rtt or baseRTT */ - vrtt = ktime_to_us(net_timedelta(last)) + 1; + vrtt = rtt_us + 1; /* Filter to find propagation delay: */ if (vrtt < vegas->baseRTT) diff --git a/net/ipv4/tcp_vegas.h b/net/ipv4/tcp_vegas.h index 502fa8183634..6c0eea2f8249 100644 --- a/net/ipv4/tcp_vegas.h +++ b/net/ipv4/tcp_vegas.h @@ -17,7 +17,7 @@ struct vegas { extern void tcp_vegas_init(struct sock *sk); extern void tcp_vegas_state(struct sock *sk, u8 ca_state); -extern void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last); +extern void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us); extern void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event); extern void tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb); diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c index 7a55ddf86032..8fb2aee0b1a4 100644 --- a/net/ipv4/tcp_veno.c +++ b/net/ipv4/tcp_veno.c @@ -69,16 +69,16 @@ static void tcp_veno_init(struct sock *sk) } /* Do rtt sampling needed for Veno. */ -static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) +static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us) { struct veno *veno = inet_csk_ca(sk); u32 vrtt; - if (ktime_equal(last, net_invalid_timestamp())) + if (rtt_us < 0) return; /* Never allow zero rtt or baseRTT */ - vrtt = ktime_to_us(net_timedelta(last)) + 1; + vrtt = rtt_us + 1; /* Filter to find propagation delay: */ if (vrtt < veno->basertt) diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c index e61e09dd513e..20151d6a6241 100644 --- a/net/ipv4/tcp_westwood.c +++ b/net/ipv4/tcp_westwood.c @@ -100,11 +100,12 @@ static void westwood_filter(struct westwood *w, u32 delta) * Called after processing group of packets. * but all westwood needs is the last sample of srtt. */ -static void tcp_westwood_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) +static void tcp_westwood_pkts_acked(struct sock *sk, u32 cnt, s32 rtt) { struct westwood *w = inet_csk_ca(sk); - if (cnt > 0) - w->rtt = tcp_sk(sk)->srtt >> 3; + + if (rtt > 0) + w->rtt = usecs_to_jiffies(rtt); } /* diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c index c04b7c6ec702..c107fba7430e 100644 --- a/net/ipv4/tcp_yeah.c +++ b/net/ipv4/tcp_yeah.c @@ -58,7 +58,7 @@ static void tcp_yeah_init(struct sock *sk) } -static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, ktime_t last) +static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, s32 rtt_us) { const struct inet_connection_sock *icsk = inet_csk(sk); struct yeah *yeah = inet_csk_ca(sk); @@ -66,7 +66,7 @@ static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, ktime_t last) if (icsk->icsk_ca_state == TCP_CA_Open) yeah->pkts_acked = pkts_acked; - tcp_vegas_pkts_acked(sk, pkts_acked, last); + tcp_vegas_pkts_acked(sk, pkts_acked, rtt_us); } static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 06012920912a..91ef3be5abad 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2256,14 +2256,14 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, struct net_device *dev = (struct net_device *) data; struct inet6_dev *idev = __in6_dev_get(dev); int run_pending = 0; + int err; switch(event) { case NETDEV_REGISTER: if (!idev && dev->mtu >= IPV6_MIN_MTU) { idev = ipv6_add_dev(dev); if (!idev) - printk(KERN_WARNING "IPv6: add_dev failed for %s\n", - dev->name); + return notifier_from_errno(-ENOMEM); } break; case NETDEV_UP: @@ -2373,7 +2373,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, NULL); addrconf_sysctl_register(idev, &idev->cnf); #endif - snmp6_register_dev(idev); + err = snmp6_register_dev(idev); + if (err) + return notifier_from_errno(err); } break; } diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c index faaefb692298..3f82e9542eda 100644 --- a/net/ipv6/addrconf_core.c +++ b/net/ipv6/addrconf_core.c @@ -50,6 +50,9 @@ int __ipv6_addr_type(const struct in6_addr *addr) if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000)) return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST | IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL)); /* addr-select 3.1 */ + if ((st & htonl(0xFE000000)) == htonl(0xFC000000)) + return (IPV6_ADDR_UNICAST | + IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* RFC 4193 */ if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) { if (addr->s6_addr32[2] == 0) { diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 36df2218b669..3153e15e0f7c 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -86,8 +86,8 @@ static int ipv6_print_conntrack(struct seq_file *s, * - Note also special handling of AUTH header. Thanks to IPsec wizards. */ -int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, - int len) +static int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start, + u8 *nexthdrp, int len) { u8 nexthdr = *nexthdrp; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 919de682b331..55ea80fac601 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1983,9 +1983,10 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) !dst_metric_locked(&rt->u.dst, RTAX_MTU) && (dst_mtu(&rt->u.dst) > arg->mtu || (dst_mtu(&rt->u.dst) < arg->mtu && - dst_mtu(&rt->u.dst) == idev->cnf.mtu6))) + dst_mtu(&rt->u.dst) == idev->cnf.mtu6))) { rt->u.dst.metrics[RTAX_MTU-1] = arg->mtu; - rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(arg->mtu); + rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(arg->mtu); + } return 0; } diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 13c09bc32aa3..dee0d5fb39c5 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -380,6 +380,10 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) return; while ((parentid = sch->parent)) { sch = qdisc_lookup(sch->dev, TC_H_MAJ(parentid)); + if (sch == NULL) { + WARN_ON(parentid != TC_H_ROOT); + return; + } cops = sch->ops->cl_ops; if (cops->qlen_notify) { cl = cops->get(sch, parentid); @@ -420,8 +424,6 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, unsigned long cl = cops->get(parent, classid); if (cl) { err = cops->graft(parent, cl, new, old); - if (new) - new->parent = classid; cops->put(parent, cl); } } @@ -436,7 +438,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, */ static struct Qdisc * -qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) +qdisc_create(struct net_device *dev, u32 parent, u32 handle, + struct rtattr **tca, int *errp) { int err; struct rtattr *kind = tca[TCA_KIND-1]; @@ -482,6 +485,8 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) goto err_out2; } + sch->parent = parent; + if (handle == TC_H_INGRESS) { sch->flags |= TCQ_F_INGRESS; sch->stats_lock = &dev->ingress_lock; @@ -758,9 +763,11 @@ create_n_graft: if (!(n->nlmsg_flags&NLM_F_CREATE)) return -ENOENT; if (clid == TC_H_INGRESS) - q = qdisc_create(dev, tcm->tcm_parent, tca, &err); + q = qdisc_create(dev, tcm->tcm_parent, tcm->tcm_parent, + tca, &err); else - q = qdisc_create(dev, tcm->tcm_handle, tca, &err); + q = qdisc_create(dev, tcm->tcm_parent, tcm->tcm_handle, + tca, &err); if (q == NULL) { if (err == -EAGAIN) goto replay; diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index 51f16b0af198..2d32fd27496e 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c @@ -158,9 +158,8 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch) break; case TC_ACT_RECLASSIFY: case TC_ACT_OK: - case TC_ACT_UNSPEC: - default: skb->tc_index = TC_H_MIN(res.classid); + default: result = TC_ACT_OK; break; } diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 2d8c08493d6e..4a49db65772e 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -38,9 +38,11 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) struct prio_sched_data *q = qdisc_priv(sch); u32 band = skb->priority; struct tcf_result res; + int err; *qerr = NET_XMIT_BYPASS; if (TC_H_MAJ(skb->priority) != sch->handle) { + err = tc_classify(skb, q->filter_list, &res); #ifdef CONFIG_NET_CLS_ACT switch (tc_classify(skb, q->filter_list, &res)) { case TC_ACT_STOLEN: @@ -49,11 +51,8 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) case TC_ACT_SHOT: return NULL; } - - if (!q->filter_list ) { -#else - if (!q->filter_list || tc_classify(skb, q->filter_list, &res)) { #endif + if (!q->filter_list || err < 0) { if (TC_H_MAJ(band)) band = 0; band = q->prio2band[band&TC_PRIO_MAX]; @@ -239,11 +238,13 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt) /* If we're multiqueue, make sure the number of incoming bands * matches the number of queues on the device we're associating with. * If the number of bands requested is zero, then set q->bands to - * dev->egress_subqueue_count. + * dev->egress_subqueue_count. Also, the root qdisc must be the + * only one that is enabled for multiqueue, since it's the only one + * that interacts with the underlying device. */ q->mq = RTA_GET_FLAG(tb[TCA_PRIO_MQ - 1]); if (q->mq) { - if (sch->handle != TC_H_ROOT) + if (sch->parent != TC_H_ROOT) return -EINVAL; if (netif_is_multiqueue(sch->dev)) { if (q->bands == 0) diff --git a/net/tipc/link.c b/net/tipc/link.c index 5adfdfd49d61..1d674e0848fa 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -423,6 +423,17 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, return NULL; } + if (LINK_LOG_BUF_SIZE) { + char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC); + + if (!pb) { + kfree(l_ptr); + warn("Link creation failed, no memory for print buffer\n"); + return NULL; + } + tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE); + } + l_ptr->addr = peer; if_name = strchr(b_ptr->publ.name, ':') + 1; sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", @@ -432,8 +443,6 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); /* note: peer i/f is appended to link name by reset/activate */ memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); - k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); - list_add_tail(&l_ptr->link_list, &b_ptr->links); l_ptr->checkpoint = 1; l_ptr->b_ptr = b_ptr; link_set_supervision_props(l_ptr, b_ptr->media->tolerance); @@ -459,21 +468,14 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, l_ptr->owner = tipc_node_attach_link(l_ptr); if (!l_ptr->owner) { + if (LINK_LOG_BUF_SIZE) + kfree(l_ptr->print_buf.buf); kfree(l_ptr); return NULL; } - if (LINK_LOG_BUF_SIZE) { - char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC); - - if (!pb) { - kfree(l_ptr); - warn("Link creation failed, no memory for print buffer\n"); - return NULL; - } - tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE); - } - + k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); + list_add_tail(&l_ptr->link_list, &b_ptr->links); tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr); dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n", diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 65ebccc0a698..a05c34260e70 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -118,14 +118,40 @@ int sysctl_unix_max_dgram_qlen __read_mostly = 10; -struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; -DEFINE_SPINLOCK(unix_table_lock); +static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; +static DEFINE_SPINLOCK(unix_table_lock); static atomic_t unix_nr_socks = ATOMIC_INIT(0); #define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE]) #define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE) +static struct sock *first_unix_socket(int *i) +{ + for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) { + if (!hlist_empty(&unix_socket_table[*i])) + return __sk_head(&unix_socket_table[*i]); + } + return NULL; +} + +static struct sock *next_unix_socket(int *i, struct sock *s) +{ + struct sock *next = sk_next(s); + /* More in this chain? */ + if (next) + return next; + /* Look for next non-empty chain. */ + for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) { + if (!hlist_empty(&unix_socket_table[*i])) + return __sk_head(&unix_socket_table[*i]); + } + return NULL; +} + +#define forall_unix_sockets(i, s) \ + for (s = first_unix_socket(&(i)); s; s = next_unix_socket(&(i),(s))) + #ifdef CONFIG_SECURITY_NETWORK static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) { diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index c3a4b0a18687..95a47304336d 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1299,7 +1299,8 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl, xfrm_address_t *local = saddr; struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i]; - if (tmpl->mode == XFRM_MODE_TUNNEL) { + if (tmpl->mode == XFRM_MODE_TUNNEL || + tmpl->mode == XFRM_MODE_BEET) { remote = &tmpl->id.daddr; local = &tmpl->saddr; family = tmpl->encap_family; diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 38f90ca75b1e..31be405efb55 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -611,7 +611,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, selector. */ if (x->km.state == XFRM_STATE_VALID) { - if (!xfrm_selector_match(&x->sel, fl, family) || + if (!xfrm_selector_match(&x->sel, fl, x->sel.family) || !security_xfrm_state_pol_flow_match(x, pol, fl)) continue; if (!best || @@ -623,7 +623,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, acquire_in_progress = 1; } else if (x->km.state == XFRM_STATE_ERROR || x->km.state == XFRM_STATE_EXPIRED) { - if (xfrm_selector_match(&x->sel, fl, family) && + if (xfrm_selector_match(&x->sel, fl, x->sel.family) && security_xfrm_state_pol_flow_match(x, pol, fl)) error = -ESRCH; } diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index c06883bf620e..61339e17a0f5 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -322,6 +322,13 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info * x->props.family = p->family; memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); x->props.flags = p->flags; + + /* + * Set inner address family if the KM left it as zero. + * See comment in validate_tmpl. + */ + if (!x->sel.family) + x->sel.family = p->family; } /*