Commit 4e5448a3 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull networking fixes from David Miller:
 "A quick set of bug fixes after there initial networking merge:

  1) Netlink multicast group storage allocator only was tested with
     nr_groups equal to 1, make it work for other values too.  From
     Matti Vaittinen.

  2) Check build_skb() return value in macb and hip04_eth drivers, from
     Weidong Wang.

  3) Don't leak x25_asy on x25_asy_open() failure.

  4) More DMA map/unmap fixes in 3c59x from Neil Horman.

  5) Don't clobber IP skb control block during GSO segmentation, from
     Konstantin Khlebnikov.

  6) ECN helpers for ipv6 don't fixup the checksum, from Eric Dumazet.

  7) Fix SKB segment utilization estimation in xen-netback, from David
     Vrabel.

  8) Fix lockdep splat in bridge addrlist handling, from Nikolay
     Aleksandrov"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (26 commits)
  bgmac: Fix reversed test of build_skb() return value.
  bridge: fix lockdep addr_list_lock false positive splat
  net: smsc: Add support h8300
  xen-netback: free queues after freeing the net device
  xen-netback: delete NAPI instance when queue fails to initialize
  xen-netback: use skb to determine number of required guest Rx requests
  net: sctp: Move sequence start handling into sctp_transport_get_idx()
  ipv6: update skb->csum when CE mark is propagated
  net: phy: turn carrier off on phy attach
  net: macb: clear interrupts when disabling them
  sctp: support to lookup with ep+paddr in transport rhashtable
  net: hns: fixes no syscon error when init mdio
  dts: hisi: fixes no syscon fault when init mdio
  net: preserve IP control block during GSO segmentation
  fsl/fman: Delete one function call "put_device" in dtsec_config()
  hip04_eth: fix missing error handle for build_skb failed
  3c59x: fix another page map/single unmap imbalance
  3c59x: balance page maps and unmaps
  x25_asy: Free x25_asy on x25_asy_open() failure.
  mlxsw: fix SWITCHDEV_OBJ_ID_PORT_MDB
  ...
parents 5a18d263 750afbf8
...@@ -187,6 +187,22 @@ Example: ...@@ -187,6 +187,22 @@ Example:
reg = <0xb0000000 0x10000>; reg = <0xb0000000 0x10000>;
}; };
Hisilicon HiP05 PERISUB system controller
Required properties:
- compatible : "hisilicon,hip05-perisubc", "syscon";
- reg : Register address and size
The HiP05 PERISUB system controller is shared by peripheral controllers in
HiP05 Soc to implement some basic configurations. The peripheral
controllers include mdio, ddr, iic, uart, timer and so on.
Example:
/* for HiP05 perisub-ctrl-c system */
peri_c_subctrl: syscon@80000000 {
compatible = "hisilicon,hip05-perisubc", "syscon";
reg = <0x0 0x80000000 0x0 0x10000>;
};
----------------------------------------------------------------------- -----------------------------------------------------------------------
Hisilicon CPU controller Hisilicon CPU controller
......
...@@ -246,6 +246,11 @@ refclk200mhz: refclk200mhz { ...@@ -246,6 +246,11 @@ refclk200mhz: refclk200mhz {
clock-frequency = <200000000>; clock-frequency = <200000000>;
}; };
peri_c_subctrl: syscon@80000000 {
compatible = "hisilicon,hip05-perisubc", "syscon";
reg = < 0x0 0x80000000 0x0 0x10000>;
};
uart0: uart@80300000 { uart0: uart@80300000 {
compatible = "snps,dw-apb-uart"; compatible = "snps,dw-apb-uart";
reg = <0x0 0x80300000 0x0 0x10000>; reg = <0x0 0x80300000 0x0 0x10000>;
......
...@@ -10,8 +10,8 @@ soc0_mdio0: mdio@803c0000 { ...@@ -10,8 +10,8 @@ soc0_mdio0: mdio@803c0000 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
compatible = "hisilicon,hns-mdio"; compatible = "hisilicon,hns-mdio";
reg = <0x0 0x803c0000 0x0 0x10000 reg = <0x0 0x803c0000 0x0 0x10000>;
0x0 0x80000000 0x0 0x10000>; subctrl-vbase = <&peri_c_subctrl>;
soc0_phy0: ethernet-phy@0 { soc0_phy0: ethernet-phy@0 {
reg = <0x0>; reg = <0x0>;
......
...@@ -2459,8 +2459,13 @@ boomerang_interrupt(int irq, void *dev_id) ...@@ -2459,8 +2459,13 @@ boomerang_interrupt(int irq, void *dev_id)
struct sk_buff *skb = vp->tx_skbuff[entry]; struct sk_buff *skb = vp->tx_skbuff[entry];
#if DO_ZEROCOPY #if DO_ZEROCOPY
int i; int i;
for (i=0; i<=skb_shinfo(skb)->nr_frags; i++) pci_unmap_single(VORTEX_PCI(vp),
pci_unmap_single(VORTEX_PCI(vp), le32_to_cpu(vp->tx_ring[entry].frag[0].addr),
le32_to_cpu(vp->tx_ring[entry].frag[0].length),
PCI_DMA_TODEVICE);
for (i=1; i<=skb_shinfo(skb)->nr_frags; i++)
pci_unmap_page(VORTEX_PCI(vp),
le32_to_cpu(vp->tx_ring[entry].frag[i].addr), le32_to_cpu(vp->tx_ring[entry].frag[i].addr),
le32_to_cpu(vp->tx_ring[entry].frag[i].length)&0xFFF, le32_to_cpu(vp->tx_ring[entry].frag[i].length)&0xFFF,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
......
...@@ -466,6 +466,11 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, ...@@ -466,6 +466,11 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
len -= ETH_FCS_LEN; len -= ETH_FCS_LEN;
skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE); skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE);
if (unlikely(!skb)) {
bgmac_err(bgmac, "build_skb failed\n");
put_page(virt_to_head_page(buf));
break;
}
skb_put(skb, BGMAC_RX_FRAME_OFFSET + skb_put(skb, BGMAC_RX_FRAME_OFFSET +
BGMAC_RX_BUF_OFFSET + len); BGMAC_RX_BUF_OFFSET + len);
skb_pull(skb, BGMAC_RX_FRAME_OFFSET + skb_pull(skb, BGMAC_RX_FRAME_OFFSET +
......
...@@ -1040,6 +1040,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) ...@@ -1040,6 +1040,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
/* close possible race with dev_close */ /* close possible race with dev_close */
if (unlikely(!netif_running(dev))) { if (unlikely(!netif_running(dev))) {
queue_writel(queue, IDR, -1); queue_writel(queue, IDR, -1);
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
queue_writel(queue, ISR, -1);
break; break;
} }
...@@ -1561,6 +1563,8 @@ static void macb_reset_hw(struct macb *bp) ...@@ -1561,6 +1563,8 @@ static void macb_reset_hw(struct macb *bp)
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
queue_writel(queue, IDR, -1); queue_writel(queue, IDR, -1);
queue_readl(queue, ISR); queue_readl(queue, ISR);
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
queue_writel(queue, ISR, -1);
} }
} }
......
...@@ -1434,7 +1434,6 @@ struct fman_mac *dtsec_config(struct fman_mac_params *params) ...@@ -1434,7 +1434,6 @@ struct fman_mac *dtsec_config(struct fman_mac_params *params)
dtsec->tbiphy = of_phy_find_device(params->internal_phy_node); dtsec->tbiphy = of_phy_find_device(params->internal_phy_node);
if (!dtsec->tbiphy) { if (!dtsec->tbiphy) {
pr_err("of_phy_find_device (TBI PHY) failed\n"); pr_err("of_phy_find_device (TBI PHY) failed\n");
put_device(&dtsec->tbiphy->mdio.dev);
goto err_dtsec_drv_param; goto err_dtsec_drv_param;
} }
......
...@@ -500,8 +500,10 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget) ...@@ -500,8 +500,10 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget)
while (cnt && !last) { while (cnt && !last) {
buf = priv->rx_buf[priv->rx_head]; buf = priv->rx_buf[priv->rx_head];
skb = build_skb(buf, priv->rx_buf_size); skb = build_skb(buf, priv->rx_buf_size);
if (unlikely(!skb)) if (unlikely(!skb)) {
net_dbg_ratelimited("build_skb failed\n"); net_dbg_ratelimited("build_skb failed\n");
goto refill;
}
dma_unmap_single(&ndev->dev, priv->rx_phys[priv->rx_head], dma_unmap_single(&ndev->dev, priv->rx_phys[priv->rx_head],
RX_BUF_SIZE, DMA_FROM_DEVICE); RX_BUF_SIZE, DMA_FROM_DEVICE);
...@@ -528,6 +530,7 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget) ...@@ -528,6 +530,7 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget)
rx++; rx++;
} }
refill:
buf = netdev_alloc_frag(priv->rx_buf_size); buf = netdev_alloc_frag(priv->rx_buf_size);
if (!buf) if (!buf)
goto done; goto done;
......
...@@ -458,7 +458,7 @@ static int hns_mdio_probe(struct platform_device *pdev) ...@@ -458,7 +458,7 @@ static int hns_mdio_probe(struct platform_device *pdev)
} }
mdio_dev->subctrl_vbase = mdio_dev->subctrl_vbase =
syscon_node_to_regmap(of_parse_phandle(np, "subctrl_vbase", 0)); syscon_node_to_regmap(of_parse_phandle(np, "subctrl-vbase", 0));
if (IS_ERR(mdio_dev->subctrl_vbase)) { if (IS_ERR(mdio_dev->subctrl_vbase)) {
dev_warn(&pdev->dev, "no syscon hisilicon,peri-c-subctrl\n"); dev_warn(&pdev->dev, "no syscon hisilicon,peri-c-subctrl\n");
mdio_dev->subctrl_vbase = NULL; mdio_dev->subctrl_vbase = NULL;
......
...@@ -1015,6 +1015,7 @@ static int mlxsw_sp_port_obj_del(struct net_device *dev, ...@@ -1015,6 +1015,7 @@ static int mlxsw_sp_port_obj_del(struct net_device *dev,
case SWITCHDEV_OBJ_ID_PORT_MDB: case SWITCHDEV_OBJ_ID_PORT_MDB:
err = mlxsw_sp_port_mdb_del(mlxsw_sp_port, err = mlxsw_sp_port_mdb_del(mlxsw_sp_port,
SWITCHDEV_OBJ_PORT_MDB(obj)); SWITCHDEV_OBJ_PORT_MDB(obj));
break;
default: default:
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
break; break;
......
...@@ -7,7 +7,7 @@ config NET_VENDOR_SMSC ...@@ -7,7 +7,7 @@ config NET_VENDOR_SMSC
default y default y
depends on ARM || ARM64 || ATARI_ETHERNAT || BLACKFIN || COLDFIRE || \ depends on ARM || ARM64 || ATARI_ETHERNAT || BLACKFIN || COLDFIRE || \
ISA || M32R || MAC || MIPS || MN10300 || NIOS2 || PCI || \ ISA || M32R || MAC || MIPS || MN10300 || NIOS2 || PCI || \
PCMCIA || SUPERH || XTENSA PCMCIA || SUPERH || XTENSA || H8300
---help--- ---help---
If you have a network (Ethernet) card belonging to this class, say Y. If you have a network (Ethernet) card belonging to this class, say Y.
...@@ -38,7 +38,7 @@ config SMC91X ...@@ -38,7 +38,7 @@ config SMC91X
select MII select MII
depends on !OF || GPIOLIB depends on !OF || GPIOLIB
depends on ARM || ARM64 || ATARI_ETHERNAT || BLACKFIN || COLDFIRE || \ depends on ARM || ARM64 || ATARI_ETHERNAT || BLACKFIN || COLDFIRE || \
M32R || MIPS || MN10300 || NIOS2 || SUPERH || XTENSA M32R || MIPS || MN10300 || NIOS2 || SUPERH || XTENSA || H8300
---help--- ---help---
This is a driver for SMC's 91x series of Ethernet chipsets, This is a driver for SMC's 91x series of Ethernet chipsets,
including the SMC91C94 and the SMC91C111. Say Y if you want it including the SMC91C94 and the SMC91C111. Say Y if you want it
......
...@@ -172,6 +172,17 @@ static inline void mcf_outsw(void *a, unsigned char *p, int l) ...@@ -172,6 +172,17 @@ static inline void mcf_outsw(void *a, unsigned char *p, int l)
#define SMC_IRQ_FLAGS 0 #define SMC_IRQ_FLAGS 0
#elif defined(CONFIG_H8300)
#define SMC_CAN_USE_8BIT 1
#define SMC_CAN_USE_16BIT 0
#define SMC_CAN_USE_32BIT 0
#define SMC_NOWAIT 0
#define SMC_inb(a, r) ioread8((a) + (r))
#define SMC_outb(v, a, r) iowrite8(v, (a) + (r))
#define SMC_insb(a, r, p, l) ioread8_rep((a) + (r), p, l)
#define SMC_outsb(a, r, p, l) iowrite8_rep((a) + (r), p, l)
#else #else
/* /*
......
...@@ -901,6 +901,11 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, ...@@ -901,6 +901,11 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
phydev->state = PHY_READY; phydev->state = PHY_READY;
/* Initial carrier state is off as the phy is about to be
* (re)initialized.
*/
netif_carrier_off(phydev->attached_dev);
/* Do initial configuration here, now that /* Do initial configuration here, now that
* we have certain key parameters * we have certain key parameters
* (dev_flags and interface) * (dev_flags and interface)
......
...@@ -571,8 +571,10 @@ static int x25_asy_open_tty(struct tty_struct *tty) ...@@ -571,8 +571,10 @@ static int x25_asy_open_tty(struct tty_struct *tty)
/* Perform the low-level X.25 async init */ /* Perform the low-level X.25 async init */
err = x25_asy_open(sl->dev); err = x25_asy_open(sl->dev);
if (err) if (err) {
x25_asy_free(sl);
return err; return err;
}
/* Done. We have linked the TTY line to a channel. */ /* Done. We have linked the TTY line to a channel. */
return 0; return 0;
} }
......
...@@ -615,6 +615,7 @@ int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref, ...@@ -615,6 +615,7 @@ int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref,
queue->tx_irq = 0; queue->tx_irq = 0;
err_unmap: err_unmap:
xenvif_unmap_frontend_rings(queue); xenvif_unmap_frontend_rings(queue);
netif_napi_del(&queue->napi);
err: err:
module_put(THIS_MODULE); module_put(THIS_MODULE);
return err; return err;
...@@ -684,22 +685,16 @@ void xenvif_deinit_queue(struct xenvif_queue *queue) ...@@ -684,22 +685,16 @@ void xenvif_deinit_queue(struct xenvif_queue *queue)
void xenvif_free(struct xenvif *vif) void xenvif_free(struct xenvif *vif)
{ {
struct xenvif_queue *queue = NULL; struct xenvif_queue *queues = vif->queues;
unsigned int num_queues = vif->num_queues; unsigned int num_queues = vif->num_queues;
unsigned int queue_index; unsigned int queue_index;
unregister_netdev(vif->dev); unregister_netdev(vif->dev);
for (queue_index = 0; queue_index < num_queues; ++queue_index) {
queue = &vif->queues[queue_index];
xenvif_deinit_queue(queue);
}
vfree(vif->queues);
vif->queues = NULL;
vif->num_queues = 0;
free_netdev(vif->dev); free_netdev(vif->dev);
for (queue_index = 0; queue_index < num_queues; ++queue_index)
xenvif_deinit_queue(&queues[queue_index]);
vfree(queues);
module_put(THIS_MODULE); module_put(THIS_MODULE);
} }
...@@ -149,20 +149,19 @@ static inline pending_ring_idx_t pending_index(unsigned i) ...@@ -149,20 +149,19 @@ static inline pending_ring_idx_t pending_index(unsigned i)
return i & (MAX_PENDING_REQS-1); return i & (MAX_PENDING_REQS-1);
} }
static int xenvif_rx_ring_slots_needed(struct xenvif *vif)
{
if (vif->gso_mask)
return DIV_ROUND_UP(vif->dev->gso_max_size, XEN_PAGE_SIZE) + 1;
else
return DIV_ROUND_UP(vif->dev->mtu, XEN_PAGE_SIZE);
}
static bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue) static bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue)
{ {
RING_IDX prod, cons; RING_IDX prod, cons;
struct sk_buff *skb;
int needed; int needed;
needed = xenvif_rx_ring_slots_needed(queue->vif); skb = skb_peek(&queue->rx_queue);
if (!skb)
return false;
needed = DIV_ROUND_UP(skb->len, XEN_PAGE_SIZE);
if (skb_is_gso(skb))
needed++;
do { do {
prod = queue->rx.sring->req_prod; prod = queue->rx.sring->req_prod;
...@@ -2005,8 +2004,7 @@ static bool xenvif_rx_queue_ready(struct xenvif_queue *queue) ...@@ -2005,8 +2004,7 @@ static bool xenvif_rx_queue_ready(struct xenvif_queue *queue)
static bool xenvif_have_rx_work(struct xenvif_queue *queue) static bool xenvif_have_rx_work(struct xenvif_queue *queue)
{ {
return (!skb_queue_empty(&queue->rx_queue) return xenvif_rx_ring_slots_available(queue)
&& xenvif_rx_ring_slots_available(queue))
|| (queue->vif->stall_timeout && || (queue->vif->stall_timeout &&
(xenvif_rx_queue_stalled(queue) (xenvif_rx_queue_stalled(queue)
|| xenvif_rx_queue_ready(queue))) || xenvif_rx_queue_ready(queue)))
......
...@@ -3551,7 +3551,8 @@ struct skb_gso_cb { ...@@ -3551,7 +3551,8 @@ struct skb_gso_cb {
int encap_level; int encap_level;
__u16 csum_start; __u16 csum_start;
}; };
#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)(skb)->cb) #define SKB_SGO_CB_OFFSET 32
#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)((skb)->cb + SKB_SGO_CB_OFFSET))
static inline int skb_tnl_header_len(const struct sk_buff *inner_skb) static inline int skb_tnl_header_len(const struct sk_buff *inner_skb)
{ {
......
...@@ -111,11 +111,24 @@ static inline void ipv4_copy_dscp(unsigned int dscp, struct iphdr *inner) ...@@ -111,11 +111,24 @@ static inline void ipv4_copy_dscp(unsigned int dscp, struct iphdr *inner)
struct ipv6hdr; struct ipv6hdr;
static inline int IP6_ECN_set_ce(struct ipv6hdr *iph) /* Note:
* IP_ECN_set_ce() has to tweak IPV4 checksum when setting CE,
* meaning both changes have no effect on skb->csum if/when CHECKSUM_COMPLETE
* In IPv6 case, no checksum compensates the change in IPv6 header,
* so we have to update skb->csum.
*/
static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph)
{ {
__be32 from, to;
if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph))) if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
return 0; return 0;
*(__be32*)iph |= htonl(INET_ECN_CE << 20);
from = *(__be32 *)iph;
to = from | htonl(INET_ECN_CE << 20);
*(__be32 *)iph = to;
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_add(csum_sub(skb->csum, from), to);
return 1; return 1;
} }
...@@ -142,7 +155,7 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb) ...@@ -142,7 +155,7 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb)
case cpu_to_be16(ETH_P_IPV6): case cpu_to_be16(ETH_P_IPV6):
if (skb_network_header(skb) + sizeof(struct ipv6hdr) <= if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
skb_tail_pointer(skb)) skb_tail_pointer(skb))
return IP6_ECN_set_ce(ipv6_hdr(skb)); return IP6_ECN_set_ce(skb, ipv6_hdr(skb));
break; break;
} }
......
...@@ -802,7 +802,9 @@ void batadv_mcast_free(struct batadv_priv *bat_priv) ...@@ -802,7 +802,9 @@ void batadv_mcast_free(struct batadv_priv *bat_priv)
batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1); batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1);
batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1); batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1);
spin_lock_bh(&bat_priv->tt.commit_lock);
batadv_mcast_mla_tt_retract(bat_priv, NULL); batadv_mcast_mla_tt_retract(bat_priv, NULL);
spin_unlock_bh(&bat_priv->tt.commit_lock);
} }
/** /**
......
...@@ -211,10 +211,6 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu) ...@@ -211,10 +211,6 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu)
hardif_neigh = container_of(rcu, struct batadv_hardif_neigh_node, rcu); hardif_neigh = container_of(rcu, struct batadv_hardif_neigh_node, rcu);
spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
hlist_del_init_rcu(&hardif_neigh->list);
spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
batadv_hardif_free_ref_now(hardif_neigh->if_incoming); batadv_hardif_free_ref_now(hardif_neigh->if_incoming);
kfree(hardif_neigh); kfree(hardif_neigh);
} }
...@@ -227,8 +223,13 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu) ...@@ -227,8 +223,13 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu)
static void static void
batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh) batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh)
{ {
if (atomic_dec_and_test(&hardif_neigh->refcount)) if (atomic_dec_and_test(&hardif_neigh->refcount)) {
spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
hlist_del_init_rcu(&hardif_neigh->list);
spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
batadv_hardif_neigh_free_rcu(&hardif_neigh->rcu); batadv_hardif_neigh_free_rcu(&hardif_neigh->rcu);
}
} }
/** /**
...@@ -238,8 +239,13 @@ batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh) ...@@ -238,8 +239,13 @@ batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh)
*/ */
void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh) void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh)
{ {
if (atomic_dec_and_test(&hardif_neigh->refcount)) if (atomic_dec_and_test(&hardif_neigh->refcount)) {
spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
hlist_del_init_rcu(&hardif_neigh->list);
spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
call_rcu(&hardif_neigh->rcu, batadv_hardif_neigh_free_rcu); call_rcu(&hardif_neigh->rcu, batadv_hardif_neigh_free_rcu);
}
} }
/** /**
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
const struct nf_br_ops __rcu *nf_br_ops __read_mostly; const struct nf_br_ops __rcu *nf_br_ops __read_mostly;
EXPORT_SYMBOL_GPL(nf_br_ops); EXPORT_SYMBOL_GPL(nf_br_ops);
static struct lock_class_key bridge_netdev_addr_lock_key;
/* net device transmit always called with BH disabled */ /* net device transmit always called with BH disabled */
netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
...@@ -87,6 +89,11 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -87,6 +89,11 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
static void br_set_lockdep_class(struct net_device *dev)
{
lockdep_set_class(&dev->addr_list_lock, &bridge_netdev_addr_lock_key);
}
static int br_dev_init(struct net_device *dev) static int br_dev_init(struct net_device *dev)
{ {
struct net_bridge *br = netdev_priv(dev); struct net_bridge *br = netdev_priv(dev);
...@@ -99,6 +106,7 @@ static int br_dev_init(struct net_device *dev) ...@@ -99,6 +106,7 @@ static int br_dev_init(struct net_device *dev)
err = br_vlan_init(br); err = br_vlan_init(br);
if (err) if (err)
free_percpu(br->stats); free_percpu(br->stats);
br_set_lockdep_class(dev);
return err; return err;
} }
......
...@@ -2695,6 +2695,8 @@ static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path) ...@@ -2695,6 +2695,8 @@ static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
* *
* It may return NULL if the skb requires no segmentation. This is * It may return NULL if the skb requires no segmentation. This is
* only possible when GSO is used for verifying header integrity. * only possible when GSO is used for verifying header integrity.
*
* Segmentation preserves SKB_SGO_CB_OFFSET bytes of previous skb cb.
*/ */
struct sk_buff *__skb_gso_segment(struct sk_buff *skb, struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
netdev_features_t features, bool tx_path) netdev_features_t features, bool tx_path)
...@@ -2709,6 +2711,9 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb, ...@@ -2709,6 +2711,9 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
return ERR_PTR(err); return ERR_PTR(err);
} }
BUILD_BUG_ON(SKB_SGO_CB_OFFSET +
sizeof(*SKB_GSO_CB(skb)) > sizeof(skb->cb));
SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb); SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb);
SKB_GSO_CB(skb)->encap_level = 0; SKB_GSO_CB(skb)->encap_level = 0;
......
...@@ -239,6 +239,7 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk, ...@@ -239,6 +239,7 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,
* from host network stack. * from host network stack.
*/ */
features = netif_skb_features(skb); features = netif_skb_features(skb);
BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET);
segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
if (IS_ERR_OR_NULL(segs)) { if (IS_ERR_OR_NULL(segs)) {
kfree_skb(skb); kfree_skb(skb);
......
...@@ -23,7 +23,7 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) ...@@ -23,7 +23,7 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
struct ipv6hdr *inner_iph = ipipv6_hdr(skb); struct ipv6hdr *inner_iph = ipipv6_hdr(skb);
if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos)) if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos))
IP6_ECN_set_ce(inner_iph); IP6_ECN_set_ce(skb, inner_iph);
} }
/* Add encapsulation header. /* Add encapsulation header.
......
...@@ -185,7 +185,7 @@ static int genl_allocate_reserve_groups(int n_groups, int *first_id) ...@@ -185,7 +185,7 @@ static int genl_allocate_reserve_groups(int n_groups, int *first_id)
} }
} }
if (id >= mc_groups_longs * BITS_PER_LONG) { if (id + n_groups > mc_groups_longs * BITS_PER_LONG) {
unsigned long new_longs = mc_groups_longs + unsigned long new_longs = mc_groups_longs +
BITS_TO_LONGS(n_groups); BITS_TO_LONGS(n_groups);
size_t nlen = new_longs * sizeof(unsigned long); size_t nlen = new_longs * sizeof(unsigned long);
......
...@@ -336,12 +336,10 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb, ...@@ -336,12 +336,10 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
unsigned short gso_type = skb_shinfo(skb)->gso_type; unsigned short gso_type = skb_shinfo(skb)->gso_type;
struct sw_flow_key later_key; struct sw_flow_key later_key;
struct sk_buff *segs, *nskb; struct sk_buff *segs, *nskb;
struct ovs_skb_cb ovs_cb;
int err; int err;
ovs_cb = *OVS_CB(skb); BUILD_BUG_ON(sizeof(*OVS_CB(skb)) > SKB_SGO_CB_OFFSET);
segs = __skb_gso_segment(skb, NETIF_F_SG, false); segs = __skb_gso_segment(skb, NETIF_F_SG, false);
*OVS_CB(skb) = ovs_cb;
if (IS_ERR(segs)) if (IS_ERR(segs))
return PTR_ERR(segs); return PTR_ERR(segs);
if (segs == NULL) if (segs == NULL)
...@@ -359,7 +357,6 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb, ...@@ -359,7 +357,6 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
/* Queue all of the segments. */ /* Queue all of the segments. */
skb = segs; skb = segs;
do { do {
*OVS_CB(skb) = ovs_cb;
if (gso_type & SKB_GSO_UDP && skb != segs) if (gso_type & SKB_GSO_UDP && skb != segs)
key = &later_key; key = &later_key;
......
...@@ -784,6 +784,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, ...@@ -784,6 +784,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
/* rhashtable for transport */ /* rhashtable for transport */
struct sctp_hash_cmp_arg { struct sctp_hash_cmp_arg {
const struct sctp_endpoint *ep;
const union sctp_addr *laddr; const union sctp_addr *laddr;
const union sctp_addr *paddr; const union sctp_addr *paddr;
const struct net *net; const struct net *net;
...@@ -797,15 +798,20 @@ static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg, ...@@ -797,15 +798,20 @@ static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg,
struct sctp_association *asoc = t->asoc; struct sctp_association *asoc = t->asoc;
const struct net *net = x->net; const struct net *net = x->net;
if (x->laddr->v4.sin_port != htons(asoc->base.bind_addr.port))
return 1;
if (!sctp_cmp_addr_exact(&t->ipaddr, x->paddr)) if (!sctp_cmp_addr_exact(&t->ipaddr, x->paddr))
return 1; return 1;
if (!net_eq(sock_net(asoc->base.sk), net)) if (!net_eq(sock_net(asoc->base.sk), net))
return 1; return 1;
if (!sctp_bind_addr_match(&asoc->base.bind_addr, if (x->ep) {
x->laddr, sctp_sk(asoc->base.sk))) if (x->ep != asoc->ep)
return 1; return 1;
} else {
if (x->laddr->v4.sin_port != htons(asoc->base.bind_addr.port))
return 1;
if (!sctp_bind_addr_match(&asoc->base.bind_addr,
x->laddr, sctp_sk(asoc->base.sk)))
return 1;
}
return 0; return 0;
} }
...@@ -832,9 +838,11 @@ static inline u32 sctp_hash_key(const void *data, u32 len, u32 seed) ...@@ -832,9 +838,11 @@ static inline u32 sctp_hash_key(const void *data, u32 len, u32 seed)
const struct sctp_hash_cmp_arg *x = data; const struct sctp_hash_cmp_arg *x = data;
const union sctp_addr *paddr = x->paddr; const union sctp_addr *paddr = x->paddr;
const struct net *net = x->net; const struct net *net = x->net;
u16 lport = x->laddr->v4.sin_port; u16 lport;
u32 addr; u32 addr;
lport = x->ep ? htons(x->ep->base.bind_addr.port) :
x->laddr->v4.sin_port;
if (paddr->sa.sa_family == AF_INET6) if (paddr->sa.sa_family == AF_INET6)
addr = jhash(&paddr->v6.sin6_addr, 16, seed); addr = jhash(&paddr->v6.sin6_addr, 16, seed);
else else
...@@ -864,12 +872,9 @@ void sctp_transport_hashtable_destroy(void) ...@@ -864,12 +872,9 @@ void sctp_transport_hashtable_destroy(void)
void sctp_hash_transport(struct sctp_transport *t) void sctp_hash_transport(struct sctp_transport *t)
{ {
struct sctp_sockaddr_entry *addr;
struct sctp_hash_cmp_arg arg; struct sctp_hash_cmp_arg arg;
addr = list_entry(t->asoc->base.bind_addr.address_list.next, arg.ep = t->asoc->ep;
struct sctp_sockaddr_entry, list);
arg.laddr = &addr->a;
arg.paddr = &t->ipaddr; arg.paddr = &t->ipaddr;
arg.net = sock_net(t->asoc->base.sk); arg.net = sock_net(t->asoc->base.sk);
...@@ -891,6 +896,7 @@ struct sctp_transport *sctp_addrs_lookup_transport( ...@@ -891,6 +896,7 @@ struct sctp_transport *sctp_addrs_lookup_transport(
const union sctp_addr *paddr) const union sctp_addr *paddr)
{ {
struct sctp_hash_cmp_arg arg = { struct sctp_hash_cmp_arg arg = {
.ep = NULL,
.laddr = laddr, .laddr = laddr,
.paddr = paddr, .paddr = paddr,
.net = net, .net = net,
...@@ -904,13 +910,15 @@ struct sctp_transport *sctp_epaddr_lookup_transport( ...@@ -904,13 +910,15 @@ struct sctp_transport *sctp_epaddr_lookup_transport(
const struct sctp_endpoint *ep, const struct sctp_endpoint *ep,
const union sctp_addr *paddr) const union sctp_addr *paddr)
{ {
struct sctp_sockaddr_entry *addr;
struct net *net = sock_net(ep->base.sk); struct net *net = sock_net(ep->base.sk);
struct sctp_hash_cmp_arg arg = {
.ep = ep,
.paddr = paddr,
.net = net,
};
addr = list_entry(ep->base.bind_addr.address_list.next, return rhashtable_lookup_fast(&sctp_transport_hashtable, &arg,
struct sctp_sockaddr_entry, list); sctp_hash_params);
return sctp_addrs_lookup_transport(net, &addr->a, paddr);
} }
/* Look up an association. */ /* Look up an association. */
......
...@@ -310,7 +310,7 @@ static struct sctp_transport *sctp_transport_get_next(struct seq_file *seq) ...@@ -310,7 +310,7 @@ static struct sctp_transport *sctp_transport_get_next(struct seq_file *seq)
static struct sctp_transport *sctp_transport_get_idx(struct seq_file *seq, static struct sctp_transport *sctp_transport_get_idx(struct seq_file *seq,
loff_t pos) loff_t pos)
{ {
void *obj; void *obj = SEQ_START_TOKEN;
while (pos && (obj = sctp_transport_get_next(seq)) && !IS_ERR(obj)) while (pos && (obj = sctp_transport_get_next(seq)) && !IS_ERR(obj))
pos--; pos--;
...@@ -347,7 +347,7 @@ static void *sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) ...@@ -347,7 +347,7 @@ static void *sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos)
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
return *pos ? sctp_transport_get_idx(seq, *pos) : SEQ_START_TOKEN; return sctp_transport_get_idx(seq, *pos);
} }
static void sctp_assocs_seq_stop(struct seq_file *seq, void *v) static void sctp_assocs_seq_stop(struct seq_file *seq, void *v)
...@@ -462,7 +462,7 @@ static void *sctp_remaddr_seq_start(struct seq_file *seq, loff_t *pos) ...@@ -462,7 +462,7 @@ static void *sctp_remaddr_seq_start(struct seq_file *seq, loff_t *pos)
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
return *pos ? sctp_transport_get_idx(seq, *pos) : SEQ_START_TOKEN; return sctp_transport_get_idx(seq, *pos);
} }
static void *sctp_remaddr_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *sctp_remaddr_seq_next(struct seq_file *seq, void *v, loff_t *pos)
......
...@@ -167,6 +167,8 @@ static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb ...@@ -167,6 +167,8 @@ static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb
{ {
struct sk_buff *segs; struct sk_buff *segs;
BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET);
BUILD_BUG_ON(sizeof(*IP6CB(skb)) > SKB_SGO_CB_OFFSET);
segs = skb_gso_segment(skb, 0); segs = skb_gso_segment(skb, 0);
kfree_skb(skb); kfree_skb(skb);
if (IS_ERR(segs)) if (IS_ERR(segs))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment