forked from Minki/linux
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 ...
This commit is contained in:
commit
4e5448a31d
@ -187,6 +187,22 @@ Example:
|
||||
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
|
||||
|
||||
|
@ -246,6 +246,11 @@
|
||||
clock-frequency = <200000000>;
|
||||
};
|
||||
|
||||
peri_c_subctrl: syscon@80000000 {
|
||||
compatible = "hisilicon,hip05-perisubc", "syscon";
|
||||
reg = < 0x0 0x80000000 0x0 0x10000>;
|
||||
};
|
||||
|
||||
uart0: uart@80300000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
reg = <0x0 0x80300000 0x0 0x10000>;
|
||||
|
@ -10,8 +10,8 @@ soc0: soc@000000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "hisilicon,hns-mdio";
|
||||
reg = <0x0 0x803c0000 0x0 0x10000
|
||||
0x0 0x80000000 0x0 0x10000>;
|
||||
reg = <0x0 0x803c0000 0x0 0x10000>;
|
||||
subctrl-vbase = <&peri_c_subctrl>;
|
||||
|
||||
soc0_phy0: ethernet-phy@0 {
|
||||
reg = <0x0>;
|
||||
|
@ -2459,8 +2459,13 @@ boomerang_interrupt(int irq, void *dev_id)
|
||||
struct sk_buff *skb = vp->tx_skbuff[entry];
|
||||
#if DO_ZEROCOPY
|
||||
int i;
|
||||
for (i=0; i<=skb_shinfo(skb)->nr_frags; i++)
|
||||
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].length)&0xFFF,
|
||||
PCI_DMA_TODEVICE);
|
||||
|
@ -466,6 +466,11 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
|
||||
len -= ETH_FCS_LEN;
|
||||
|
||||
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 +
|
||||
BGMAC_RX_BUF_OFFSET + len);
|
||||
skb_pull(skb, BGMAC_RX_FRAME_OFFSET +
|
||||
|
@ -1040,6 +1040,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
|
||||
/* close possible race with dev_close */
|
||||
if (unlikely(!netif_running(dev))) {
|
||||
queue_writel(queue, IDR, -1);
|
||||
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
|
||||
queue_writel(queue, ISR, -1);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1561,6 +1563,8 @@ static void macb_reset_hw(struct macb *bp)
|
||||
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
|
||||
queue_writel(queue, IDR, -1);
|
||||
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)
|
||||
dtsec->tbiphy = of_phy_find_device(params->internal_phy_node);
|
||||
if (!dtsec->tbiphy) {
|
||||
pr_err("of_phy_find_device (TBI PHY) failed\n");
|
||||
put_device(&dtsec->tbiphy->mdio.dev);
|
||||
goto err_dtsec_drv_param;
|
||||
}
|
||||
|
||||
|
@ -500,8 +500,10 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget)
|
||||
while (cnt && !last) {
|
||||
buf = priv->rx_buf[priv->rx_head];
|
||||
skb = build_skb(buf, priv->rx_buf_size);
|
||||
if (unlikely(!skb))
|
||||
if (unlikely(!skb)) {
|
||||
net_dbg_ratelimited("build_skb failed\n");
|
||||
goto refill;
|
||||
}
|
||||
|
||||
dma_unmap_single(&ndev->dev, priv->rx_phys[priv->rx_head],
|
||||
RX_BUF_SIZE, DMA_FROM_DEVICE);
|
||||
@ -528,6 +530,7 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget)
|
||||
rx++;
|
||||
}
|
||||
|
||||
refill:
|
||||
buf = netdev_alloc_frag(priv->rx_buf_size);
|
||||
if (!buf)
|
||||
goto done;
|
||||
|
@ -458,7 +458,7 @@ static int hns_mdio_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
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)) {
|
||||
dev_warn(&pdev->dev, "no syscon hisilicon,peri-c-subctrl\n");
|
||||
mdio_dev->subctrl_vbase = NULL;
|
||||
|
@ -1015,6 +1015,7 @@ static int mlxsw_sp_port_obj_del(struct net_device *dev,
|
||||
case SWITCHDEV_OBJ_ID_PORT_MDB:
|
||||
err = mlxsw_sp_port_mdb_del(mlxsw_sp_port,
|
||||
SWITCHDEV_OBJ_PORT_MDB(obj));
|
||||
break;
|
||||
default:
|
||||
err = -EOPNOTSUPP;
|
||||
break;
|
||||
|
@ -7,7 +7,7 @@ config NET_VENDOR_SMSC
|
||||
default y
|
||||
depends on ARM || ARM64 || ATARI_ETHERNAT || BLACKFIN || COLDFIRE || \
|
||||
ISA || M32R || MAC || MIPS || MN10300 || NIOS2 || PCI || \
|
||||
PCMCIA || SUPERH || XTENSA
|
||||
PCMCIA || SUPERH || XTENSA || H8300
|
||||
---help---
|
||||
If you have a network (Ethernet) card belonging to this class, say Y.
|
||||
|
||||
@ -38,7 +38,7 @@ config SMC91X
|
||||
select MII
|
||||
depends on !OF || GPIOLIB
|
||||
depends on ARM || ARM64 || ATARI_ETHERNAT || BLACKFIN || COLDFIRE || \
|
||||
M32R || MIPS || MN10300 || NIOS2 || SUPERH || XTENSA
|
||||
M32R || MIPS || MN10300 || NIOS2 || SUPERH || XTENSA || H8300
|
||||
---help---
|
||||
This is a driver for SMC's 91x series of Ethernet chipsets,
|
||||
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)
|
||||
|
||||
#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
|
||||
|
||||
/*
|
||||
|
@ -901,6 +901,11 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
|
||||
|
||||
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
|
||||
* we have certain key parameters
|
||||
* (dev_flags and interface)
|
||||
|
@ -571,8 +571,10 @@ static int x25_asy_open_tty(struct tty_struct *tty)
|
||||
|
||||
/* Perform the low-level X.25 async init */
|
||||
err = x25_asy_open(sl->dev);
|
||||
if (err)
|
||||
if (err) {
|
||||
x25_asy_free(sl);
|
||||
return err;
|
||||
}
|
||||
/* Done. We have linked the TTY line to a channel. */
|
||||
return 0;
|
||||
}
|
||||
|
@ -615,6 +615,7 @@ err_tx_unbind:
|
||||
queue->tx_irq = 0;
|
||||
err_unmap:
|
||||
xenvif_unmap_frontend_rings(queue);
|
||||
netif_napi_del(&queue->napi);
|
||||
err:
|
||||
module_put(THIS_MODULE);
|
||||
return err;
|
||||
@ -684,22 +685,16 @@ void xenvif_deinit_queue(struct xenvif_queue *queue)
|
||||
|
||||
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 queue_index;
|
||||
|
||||
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);
|
||||
|
||||
for (queue_index = 0; queue_index < num_queues; ++queue_index)
|
||||
xenvif_deinit_queue(&queues[queue_index]);
|
||||
vfree(queues);
|
||||
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
@ -149,20 +149,19 @@ static inline pending_ring_idx_t pending_index(unsigned i)
|
||||
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)
|
||||
{
|
||||
RING_IDX prod, cons;
|
||||
struct sk_buff *skb;
|
||||
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 {
|
||||
prod = queue->rx.sring->req_prod;
|
||||
@ -2005,8 +2004,7 @@ static bool xenvif_rx_queue_ready(struct xenvif_queue *queue)
|
||||
|
||||
static bool xenvif_have_rx_work(struct xenvif_queue *queue)
|
||||
{
|
||||
return (!skb_queue_empty(&queue->rx_queue)
|
||||
&& xenvif_rx_ring_slots_available(queue))
|
||||
return xenvif_rx_ring_slots_available(queue)
|
||||
|| (queue->vif->stall_timeout &&
|
||||
(xenvif_rx_queue_stalled(queue)
|
||||
|| xenvif_rx_queue_ready(queue)))
|
||||
|
@ -3551,7 +3551,8 @@ struct skb_gso_cb {
|
||||
int encap_level;
|
||||
__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)
|
||||
{
|
||||
|
@ -111,11 +111,24 @@ static inline void ipv4_copy_dscp(unsigned int dscp, struct iphdr *inner)
|
||||
|
||||
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)))
|
||||
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;
|
||||
}
|
||||
|
||||
@ -142,7 +155,7 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb)
|
||||
case cpu_to_be16(ETH_P_IPV6):
|
||||
if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
|
||||
skb_tail_pointer(skb))
|
||||
return IP6_ECN_set_ce(ipv6_hdr(skb));
|
||||
return IP6_ECN_set_ce(skb, ipv6_hdr(skb));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -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_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1);
|
||||
|
||||
spin_lock_bh(&bat_priv->tt.commit_lock);
|
||||
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)
|
||||
|
||||
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);
|
||||
kfree(hardif_neigh);
|
||||
}
|
||||
@ -227,8 +223,13 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu)
|
||||
static void
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,6 +28,8 @@
|
||||
const struct nf_br_ops __rcu *nf_br_ops __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(nf_br_ops);
|
||||
|
||||
static struct lock_class_key bridge_netdev_addr_lock_key;
|
||||
|
||||
/* net device transmit always called with BH disabled */
|
||||
netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
@ -87,6 +89,11 @@ out:
|
||||
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)
|
||||
{
|
||||
struct net_bridge *br = netdev_priv(dev);
|
||||
@ -99,6 +106,7 @@ static int br_dev_init(struct net_device *dev)
|
||||
err = br_vlan_init(br);
|
||||
if (err)
|
||||
free_percpu(br->stats);
|
||||
br_set_lockdep_class(dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -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
|
||||
* 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,
|
||||
netdev_features_t features, bool tx_path)
|
||||
@ -2709,6 +2711,9 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
|
||||
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)->encap_level = 0;
|
||||
|
||||
|
@ -239,6 +239,7 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,
|
||||
* from host network stack.
|
||||
*/
|
||||
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);
|
||||
if (IS_ERR_OR_NULL(segs)) {
|
||||
kfree_skb(skb);
|
||||
|
@ -23,7 +23,7 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
|
||||
struct ipv6hdr *inner_iph = ipipv6_hdr(skb);
|
||||
|
||||
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.
|
||||
|
@ -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 +
|
||||
BITS_TO_LONGS(n_groups);
|
||||
size_t nlen = new_longs * sizeof(unsigned long);
|
||||
|
@ -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;
|
||||
struct sw_flow_key later_key;
|
||||
struct sk_buff *segs, *nskb;
|
||||
struct ovs_skb_cb ovs_cb;
|
||||
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);
|
||||
*OVS_CB(skb) = ovs_cb;
|
||||
if (IS_ERR(segs))
|
||||
return PTR_ERR(segs);
|
||||
if (segs == NULL)
|
||||
@ -359,7 +357,6 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
|
||||
/* Queue all of the segments. */
|
||||
skb = segs;
|
||||
do {
|
||||
*OVS_CB(skb) = ovs_cb;
|
||||
if (gso_type & SKB_GSO_UDP && skb != segs)
|
||||
key = &later_key;
|
||||
|
||||
|
@ -784,6 +784,7 @@ hit:
|
||||
|
||||
/* rhashtable for transport */
|
||||
struct sctp_hash_cmp_arg {
|
||||
const struct sctp_endpoint *ep;
|
||||
const union sctp_addr *laddr;
|
||||
const union sctp_addr *paddr;
|
||||
const struct net *net;
|
||||
@ -797,15 +798,20 @@ static inline int sctp_hash_cmp(struct rhashtable_compare_arg *arg,
|
||||
struct sctp_association *asoc = t->asoc;
|
||||
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))
|
||||
return 1;
|
||||
if (!net_eq(sock_net(asoc->base.sk), net))
|
||||
return 1;
|
||||
if (x->ep) {
|
||||
if (x->ep != asoc->ep)
|
||||
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;
|
||||
}
|
||||
@ -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 union sctp_addr *paddr = x->paddr;
|
||||
const struct net *net = x->net;
|
||||
u16 lport = x->laddr->v4.sin_port;
|
||||
u16 lport;
|
||||
u32 addr;
|
||||
|
||||
lport = x->ep ? htons(x->ep->base.bind_addr.port) :
|
||||
x->laddr->v4.sin_port;
|
||||
if (paddr->sa.sa_family == AF_INET6)
|
||||
addr = jhash(&paddr->v6.sin6_addr, 16, seed);
|
||||
else
|
||||
@ -864,12 +872,9 @@ void sctp_transport_hashtable_destroy(void)
|
||||
|
||||
void sctp_hash_transport(struct sctp_transport *t)
|
||||
{
|
||||
struct sctp_sockaddr_entry *addr;
|
||||
struct sctp_hash_cmp_arg arg;
|
||||
|
||||
addr = list_entry(t->asoc->base.bind_addr.address_list.next,
|
||||
struct sctp_sockaddr_entry, list);
|
||||
arg.laddr = &addr->a;
|
||||
arg.ep = t->asoc->ep;
|
||||
arg.paddr = &t->ipaddr;
|
||||
arg.net = sock_net(t->asoc->base.sk);
|
||||
|
||||
@ -891,6 +896,7 @@ struct sctp_transport *sctp_addrs_lookup_transport(
|
||||
const union sctp_addr *paddr)
|
||||
{
|
||||
struct sctp_hash_cmp_arg arg = {
|
||||
.ep = NULL,
|
||||
.laddr = laddr,
|
||||
.paddr = paddr,
|
||||
.net = net,
|
||||
@ -904,13 +910,15 @@ struct sctp_transport *sctp_epaddr_lookup_transport(
|
||||
const struct sctp_endpoint *ep,
|
||||
const union sctp_addr *paddr)
|
||||
{
|
||||
struct sctp_sockaddr_entry *addr;
|
||||
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,
|
||||
struct sctp_sockaddr_entry, list);
|
||||
|
||||
return sctp_addrs_lookup_transport(net, &addr->a, paddr);
|
||||
return rhashtable_lookup_fast(&sctp_transport_hashtable, &arg,
|
||||
sctp_hash_params);
|
||||
}
|
||||
|
||||
/* Look up an association. */
|
||||
|
@ -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,
|
||||
loff_t pos)
|
||||
{
|
||||
void *obj;
|
||||
void *obj = SEQ_START_TOKEN;
|
||||
|
||||
while (pos && (obj = sctp_transport_get_next(seq)) && !IS_ERR(obj))
|
||||
pos--;
|
||||
@ -347,7 +347,7 @@ static void *sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
if (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)
|
||||
@ -462,7 +462,7 @@ static void *sctp_remaddr_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
if (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)
|
||||
|
@ -167,6 +167,8 @@ static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb
|
||||
{
|
||||
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);
|
||||
kfree_skb(skb);
|
||||
if (IS_ERR(segs))
|
||||
|
Loading…
Reference in New Issue
Block a user