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

Pull networking fixes from David Miller:

 1) Fix ppp_mppe crypto soft dependencies, from Takashi Iawi.

 2) Fix TX completion to be finite, from Sergej Benilov.

 3) Use register_pernet_device to avoid a dst leak in tipc, from Xin
    Long.

 4) Double free of TX cleanup in Dirk van der Merwe.

 5) Memory leak in packet_set_ring(), from Eric Dumazet.

 6) Out of bounds read in qmi_wwan, from Bjørn Mork.

 7) Fix iif used in mcast/bcast looped back packets, from Stephen
    Suryaputra.

 8) Fix neighbour resolution on raw ipv6 sockets, from Nicolas Dichtel.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (25 commits)
  af_packet: Block execution of tasks waiting for transmit to complete in AF_PACKET
  sctp: change to hold sk after auth shkey is created successfully
  ipv6: fix neighbour resolution with raw socket
  ipv6: constify rt6_nexthop()
  net: dsa: microchip: Use gpiod_set_value_cansleep()
  net: aquantia: fix vlans not working over bridged network
  ipv4: reset rt_iif for recirculated mcast/bcast out pkts
  team: Always enable vlan tx offload
  net/smc: Fix error path in smc_init
  net/smc: hold conns_lock before calling smc_lgr_register_conn()
  bonding: Always enable vlan tx offload
  net/ipv6: Fix misuse of proc_dointvec "skip_notify_on_dev_down"
  ipv4: Use return value of inet_iif() for __raw_v4_lookup in the while loop
  qmi_wwan: Fix out-of-bounds read
  tipc: check msg->req data len in tipc_nl_compat_bearer_disable
  net: macb: do not copy the mac address if NULL
  net/packet: fix memory leak in packet_set_ring()
  net/tls: fix page double free on TX cleanup
  net/sched: cbs: Fix error path of cbs_module_init
  tipc: change to use register_pernet_device
  ...
This commit is contained in:
Linus Torvalds 2019-06-28 08:24:37 +08:00
commit c84afab02c
34 changed files with 194 additions and 84 deletions

View File

@ -4320,12 +4320,12 @@ void bond_setup(struct net_device *bond_dev)
bond_dev->features |= NETIF_F_NETNS_LOCAL; bond_dev->features |= NETIF_F_NETNS_LOCAL;
bond_dev->hw_features = BOND_VLAN_FEATURES | bond_dev->hw_features = BOND_VLAN_FEATURES |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER; NETIF_F_HW_VLAN_CTAG_FILTER;
bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4; bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
bond_dev->features |= bond_dev->hw_features; bond_dev->features |= bond_dev->hw_features;
bond_dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
} }
/* Destroy a bonding device. /* Destroy a bonding device.

View File

@ -436,9 +436,9 @@ int ksz_switch_register(struct ksz_device *dev,
return PTR_ERR(dev->reset_gpio); return PTR_ERR(dev->reset_gpio);
if (dev->reset_gpio) { if (dev->reset_gpio) {
gpiod_set_value(dev->reset_gpio, 1); gpiod_set_value_cansleep(dev->reset_gpio, 1);
mdelay(10); mdelay(10);
gpiod_set_value(dev->reset_gpio, 0); gpiod_set_value_cansleep(dev->reset_gpio, 0);
} }
mutex_init(&dev->dev_mutex); mutex_init(&dev->dev_mutex);
@ -487,7 +487,7 @@ void ksz_switch_remove(struct ksz_device *dev)
dsa_unregister_switch(dev->ds); dsa_unregister_switch(dev->ds);
if (dev->reset_gpio) if (dev->reset_gpio)
gpiod_set_value(dev->reset_gpio, 1); gpiod_set_value_cansleep(dev->reset_gpio, 1);
} }
EXPORT_SYMBOL(ksz_switch_remove); EXPORT_SYMBOL(ksz_switch_remove);

View File

@ -843,9 +843,14 @@ int aq_filters_vlans_update(struct aq_nic_s *aq_nic)
return err; return err;
if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) { if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) {
if (hweight < AQ_VLAN_MAX_FILTERS) if (hweight < AQ_VLAN_MAX_FILTERS && hweight > 0) {
err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, true); err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw,
!(aq_nic->packet_filter & IFF_PROMISC));
aq_nic->aq_nic_cfg.is_vlan_force_promisc = false;
} else {
/* otherwise left in promiscue mode */ /* otherwise left in promiscue mode */
aq_nic->aq_nic_cfg.is_vlan_force_promisc = true;
}
} }
return err; return err;
@ -866,6 +871,7 @@ int aq_filters_vlan_offload_off(struct aq_nic_s *aq_nic)
if (unlikely(!aq_hw_ops->hw_filter_vlan_ctrl)) if (unlikely(!aq_hw_ops->hw_filter_vlan_ctrl))
return -EOPNOTSUPP; return -EOPNOTSUPP;
aq_nic->aq_nic_cfg.is_vlan_force_promisc = true;
err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, false); err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, false);
if (err) if (err)
return err; return err;

View File

@ -126,6 +126,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self)
cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk; cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk;
cfg->features = cfg->aq_hw_caps->hw_features; cfg->features = cfg->aq_hw_caps->hw_features;
cfg->is_vlan_force_promisc = true;
} }
static int aq_nic_update_link_status(struct aq_nic_s *self) static int aq_nic_update_link_status(struct aq_nic_s *self)

View File

@ -35,6 +35,7 @@ struct aq_nic_cfg_s {
u32 flow_control; u32 flow_control;
u32 link_speed_msk; u32 link_speed_msk;
u32 wol; u32 wol;
bool is_vlan_force_promisc;
u16 is_mc_list_enabled; u16 is_mc_list_enabled;
u16 mc_list_count; u16 mc_list_count;
bool is_autoneg; bool is_autoneg;

View File

@ -778,8 +778,15 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,
unsigned int packet_filter) unsigned int packet_filter)
{ {
unsigned int i = 0U; unsigned int i = 0U;
struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
hw_atl_rpfl2promiscuous_mode_en_set(self,
IS_FILTER_ENABLED(IFF_PROMISC));
hw_atl_rpf_vlan_prom_mode_en_set(self,
IS_FILTER_ENABLED(IFF_PROMISC) ||
cfg->is_vlan_force_promisc);
hw_atl_rpfl2promiscuous_mode_en_set(self, IS_FILTER_ENABLED(IFF_PROMISC));
hw_atl_rpfl2multicast_flr_en_set(self, hw_atl_rpfl2multicast_flr_en_set(self,
IS_FILTER_ENABLED(IFF_ALLMULTI), 0); IS_FILTER_ENABLED(IFF_ALLMULTI), 0);
@ -788,13 +795,13 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,
hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST)); hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST));
self->aq_nic_cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST); cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST);
for (i = HW_ATL_B0_MAC_MIN; i < HW_ATL_B0_MAC_MAX; ++i) for (i = HW_ATL_B0_MAC_MIN; i < HW_ATL_B0_MAC_MAX; ++i)
hw_atl_rpfl2_uc_flr_en_set(self, hw_atl_rpfl2_uc_flr_en_set(self,
(self->aq_nic_cfg->is_mc_list_enabled && (cfg->is_mc_list_enabled &&
(i <= self->aq_nic_cfg->mc_list_count)) ? (i <= cfg->mc_list_count)) ?
1U : 0U, i); 1U : 0U, i);
return aq_hw_err_from_flags(self); return aq_hw_err_from_flags(self);
} }
@ -1086,7 +1093,7 @@ static int hw_atl_b0_hw_vlan_set(struct aq_hw_s *self,
static int hw_atl_b0_hw_vlan_ctrl(struct aq_hw_s *self, bool enable) static int hw_atl_b0_hw_vlan_ctrl(struct aq_hw_s *self, bool enable)
{ {
/* set promisc in case of disabing the vland filter */ /* set promisc in case of disabing the vland filter */
hw_atl_rpf_vlan_prom_mode_en_set(self, !!!enable); hw_atl_rpf_vlan_prom_mode_en_set(self, !enable);
return aq_hw_err_from_flags(self); return aq_hw_err_from_flags(self);
} }

View File

@ -4180,7 +4180,7 @@ static int macb_probe(struct platform_device *pdev)
if (PTR_ERR(mac) == -EPROBE_DEFER) { if (PTR_ERR(mac) == -EPROBE_DEFER) {
err = -EPROBE_DEFER; err = -EPROBE_DEFER;
goto err_out_free_netdev; goto err_out_free_netdev;
} else if (!IS_ERR(mac)) { } else if (!IS_ERR_OR_NULL(mac)) {
ether_addr_copy(bp->dev->dev_addr, mac); ether_addr_copy(bp->dev->dev_addr, mac);
} else { } else {
macb_get_hwaddr(bp); macb_get_hwaddr(bp);

View File

@ -891,7 +891,7 @@ static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
u64 *data) u64 *data)
{ {
struct be_adapter *adapter = netdev_priv(netdev); struct be_adapter *adapter = netdev_priv(netdev);
int status; int status, cnt;
u8 link_status = 0; u8 link_status = 0;
if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) { if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) {
@ -902,6 +902,9 @@ static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
/* check link status before offline tests */
link_status = netif_carrier_ok(netdev);
if (test->flags & ETH_TEST_FL_OFFLINE) { if (test->flags & ETH_TEST_FL_OFFLINE) {
if (be_loopback_test(adapter, BE_MAC_LOOPBACK, &data[0]) != 0) if (be_loopback_test(adapter, BE_MAC_LOOPBACK, &data[0]) != 0)
test->flags |= ETH_TEST_FL_FAILED; test->flags |= ETH_TEST_FL_FAILED;
@ -922,13 +925,26 @@ static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
test->flags |= ETH_TEST_FL_FAILED; test->flags |= ETH_TEST_FL_FAILED;
} }
status = be_cmd_link_status_query(adapter, NULL, &link_status, 0); /* link status was down prior to test */
if (status) { if (!link_status) {
test->flags |= ETH_TEST_FL_FAILED;
data[4] = -1;
} else if (!link_status) {
test->flags |= ETH_TEST_FL_FAILED; test->flags |= ETH_TEST_FL_FAILED;
data[4] = 1; data[4] = 1;
return;
}
for (cnt = 10; cnt; cnt--) {
status = be_cmd_link_status_query(adapter, NULL, &link_status,
0);
if (status) {
test->flags |= ETH_TEST_FL_FAILED;
data[4] = -1;
break;
}
if (link_status)
break;
msleep_interruptible(500);
} }
} }

View File

@ -1057,7 +1057,7 @@ sis900_open(struct net_device *net_dev)
sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
/* Enable all known interrupts by setting the interrupt mask. */ /* Enable all known interrupts by setting the interrupt mask. */
sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE | TxDESC);
sw32(cr, RxENA | sr32(cr)); sw32(cr, RxENA | sr32(cr));
sw32(ier, IE); sw32(ier, IE);
@ -1578,7 +1578,7 @@ static void sis900_tx_timeout(struct net_device *net_dev)
sw32(txdp, sis_priv->tx_ring_dma); sw32(txdp, sis_priv->tx_ring_dma);
/* Enable all known interrupts by setting the interrupt mask. */ /* Enable all known interrupts by setting the interrupt mask. */
sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE | TxDESC);
} }
/** /**
@ -1618,7 +1618,7 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
spin_unlock_irqrestore(&sis_priv->lock, flags); spin_unlock_irqrestore(&sis_priv->lock, flags);
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len); sis_priv->tx_ring[entry].cmdsts = (OWN | INTR | skb->len);
sw32(cr, TxENA | sr32(cr)); sw32(cr, TxENA | sr32(cr));
sis_priv->cur_tx ++; sis_priv->cur_tx ++;
@ -1674,7 +1674,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance)
do { do {
status = sr32(isr); status = sr32(isr);
if ((status & (HIBERR|TxURN|TxERR|TxIDLE|RxORN|RxERR|RxOK)) == 0) if ((status & (HIBERR|TxURN|TxERR|TxIDLE|TxDESC|RxORN|RxERR|RxOK)) == 0)
/* nothing intresting happened */ /* nothing intresting happened */
break; break;
handled = 1; handled = 1;
@ -1684,7 +1684,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance)
/* Rx interrupt */ /* Rx interrupt */
sis900_rx(net_dev); sis900_rx(net_dev);
if (status & (TxURN | TxERR | TxIDLE)) if (status & (TxURN | TxERR | TxIDLE | TxDESC))
/* Tx interrupt */ /* Tx interrupt */
sis900_finish_xmit(net_dev); sis900_finish_xmit(net_dev);
@ -1896,8 +1896,8 @@ static void sis900_finish_xmit (struct net_device *net_dev)
if (tx_status & OWN) { if (tx_status & OWN) {
/* The packet is not transmitted yet (owned by hardware) ! /* The packet is not transmitted yet (owned by hardware) !
* Note: the interrupt is generated only when Tx Machine * Note: this is an almost impossible condition
* is idle, so this is an almost impossible case */ * in case of TxDESC ('descriptor interrupt') */
break; break;
} }
@ -2473,7 +2473,7 @@ static int sis900_resume(struct pci_dev *pci_dev)
sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
/* Enable all known interrupts by setting the interrupt mask. */ /* Enable all known interrupts by setting the interrupt mask. */
sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE | TxDESC);
sw32(cr, RxENA | sr32(cr)); sw32(cr, RxENA | sr32(cr));
sw32(ier, IE); sw32(ier, IE);

View File

@ -112,7 +112,7 @@ static int adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec,
* programmed with (2^32 <new_sec_value>) * programmed with (2^32 <new_sec_value>)
*/ */
if (gmac4) if (gmac4)
sec = (100000000ULL - sec); sec = -sec;
value = readl(ioaddr + PTP_TCR); value = readl(ioaddr + PTP_TCR);
if (value & PTP_TCR_TSCTRLSSR) if (value & PTP_TCR_TSCTRLSSR)

View File

@ -2947,12 +2947,15 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
/* Manage tx mitigation */ /* Manage tx mitigation */
tx_q->tx_count_frames += nfrags + 1; tx_q->tx_count_frames += nfrags + 1;
if (priv->tx_coal_frames <= tx_q->tx_count_frames) { if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) &&
!(priv->synopsys_id >= DWMAC_CORE_4_00 &&
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
priv->hwts_tx_en)) {
stmmac_tx_timer_arm(priv, queue);
} else {
tx_q->tx_count_frames = 0;
stmmac_set_tx_ic(priv, desc); stmmac_set_tx_ic(priv, desc);
priv->xstats.tx_set_ic_bit++; priv->xstats.tx_set_ic_bit++;
tx_q->tx_count_frames = 0;
} else {
stmmac_tx_timer_arm(priv, queue);
} }
skb_tx_timestamp(skb); skb_tx_timestamp(skb);
@ -3166,12 +3169,15 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
* element in case of no SG. * element in case of no SG.
*/ */
tx_q->tx_count_frames += nfrags + 1; tx_q->tx_count_frames += nfrags + 1;
if (priv->tx_coal_frames <= tx_q->tx_count_frames) { if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) &&
!(priv->synopsys_id >= DWMAC_CORE_4_00 &&
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
priv->hwts_tx_en)) {
stmmac_tx_timer_arm(priv, queue);
} else {
tx_q->tx_count_frames = 0;
stmmac_set_tx_ic(priv, desc); stmmac_set_tx_ic(priv, desc);
priv->xstats.tx_set_ic_bit++; priv->xstats.tx_set_ic_bit++;
tx_q->tx_count_frames = 0;
} else {
stmmac_tx_timer_arm(priv, queue);
} }
skb_tx_timestamp(skb); skb_tx_timestamp(skb);

View File

@ -63,6 +63,7 @@ MODULE_AUTHOR("Frank Cusack <fcusack@fcusack.com>");
MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support"); MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE)); MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
MODULE_SOFTDEP("pre: arc4");
MODULE_VERSION("1.0.2"); MODULE_VERSION("1.0.2");
static unsigned int static unsigned int

View File

@ -2128,12 +2128,12 @@ static void team_setup(struct net_device *dev)
dev->features |= NETIF_F_NETNS_LOCAL; dev->features |= NETIF_F_NETNS_LOCAL;
dev->hw_features = TEAM_VLAN_FEATURES | dev->hw_features = TEAM_VLAN_FEATURES |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER; NETIF_F_HW_VLAN_CTAG_FILTER;
dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4; dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
dev->features |= dev->hw_features; dev->features |= dev->hw_features;
dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
} }
static int team_newlink(struct net *src_net, struct net_device *dev, static int team_newlink(struct net *src_net, struct net_device *dev,

View File

@ -1482,7 +1482,7 @@ static int qmi_wwan_probe(struct usb_interface *intf,
* different. Ignore the current interface if the number of endpoints * different. Ignore the current interface if the number of endpoints
* equals the number for the diag interface (two). * equals the number for the diag interface (two).
*/ */
info = (void *)&id->driver_info; info = (void *)id->driver_info;
if (info->data & QMI_WWAN_QUIRK_QUECTEL_DYNCFG) { if (info->data & QMI_WWAN_QUIRK_QUECTEL_DYNCFG) {
if (desc->bNumEndpoints == 2) if (desc->bNumEndpoints == 2)

View File

@ -350,8 +350,8 @@ static int vrf_finish_output6(struct net *net, struct sock *sk,
{ {
struct dst_entry *dst = skb_dst(skb); struct dst_entry *dst = skb_dst(skb);
struct net_device *dev = dst->dev; struct net_device *dev = dst->dev;
const struct in6_addr *nexthop;
struct neighbour *neigh; struct neighbour *neigh;
struct in6_addr *nexthop;
int ret; int ret;
nf_reset(skb); nf_reset(skb);

View File

@ -262,8 +262,8 @@ static inline bool ip6_sk_ignore_df(const struct sock *sk)
inet6_sk(sk)->pmtudisc == IPV6_PMTUDISC_OMIT; inet6_sk(sk)->pmtudisc == IPV6_PMTUDISC_OMIT;
} }
static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt, static inline const struct in6_addr *rt6_nexthop(const struct rt6_info *rt,
struct in6_addr *daddr) const struct in6_addr *daddr)
{ {
if (rt->rt6i_flags & RTF_GATEWAY) if (rt->rt6i_flags & RTF_GATEWAY)
return &rt->rt6i_gateway; return &rt->rt6i_gateway;

View File

@ -221,6 +221,7 @@ void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt);
struct rtable *rt_dst_alloc(struct net_device *dev, struct rtable *rt_dst_alloc(struct net_device *dev,
unsigned int flags, u16 type, unsigned int flags, u16 type,
bool nopolicy, bool noxfrm, bool will_cache); bool nopolicy, bool noxfrm, bool will_cache);
struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt);
struct in_ifaddr; struct in_ifaddr;
void fib_add_ifaddr(struct in_ifaddr *); void fib_add_ifaddr(struct in_ifaddr *);

View File

@ -373,21 +373,6 @@ static inline bool tls_is_partially_sent_record(struct tls_context *ctx)
return !!ctx->partially_sent_record; return !!ctx->partially_sent_record;
} }
static inline int tls_complete_pending_work(struct sock *sk,
struct tls_context *ctx,
int flags, long *timeo)
{
int rc = 0;
if (unlikely(sk->sk_write_pending))
rc = wait_on_pending_writer(sk, timeo);
if (!rc && tls_is_partially_sent_record(ctx))
rc = tls_push_partial_record(sk, ctx, flags);
return rc;
}
static inline bool tls_is_pending_open_record(struct tls_context *tls_ctx) static inline bool tls_is_pending_open_record(struct tls_context *tls_ctx)
{ {
return tls_ctx->pending_open_record_frags; return tls_ctx->pending_open_record_frags;

View File

@ -160,10 +160,10 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
struct in6_addr *daddr, struct in6_addr *daddr,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct lowpan_peer *peer;
struct in6_addr *nexthop;
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
int count = atomic_read(&dev->peer_count); int count = atomic_read(&dev->peer_count);
const struct in6_addr *nexthop;
struct lowpan_peer *peer;
BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt); BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);

View File

@ -318,6 +318,7 @@ static int ip_finish_output(struct net *net, struct sock *sk, struct sk_buff *sk
static int ip_mc_finish_output(struct net *net, struct sock *sk, static int ip_mc_finish_output(struct net *net, struct sock *sk,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct rtable *new_rt;
int ret; int ret;
ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb); ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb);
@ -326,6 +327,17 @@ static int ip_mc_finish_output(struct net *net, struct sock *sk,
return ret; return ret;
} }
/* Reset rt_iif so that inet_iif() will return skb->skb_iif. Setting
* this to non-zero causes ipi_ifindex in in_pktinfo to be overwritten,
* see ipv4_pktinfo_prepare().
*/
new_rt = rt_dst_clone(net->loopback_dev, skb_rtable(skb));
if (new_rt) {
new_rt->rt_iif = 0;
skb_dst_drop(skb);
skb_dst_set(skb, &new_rt->dst);
}
return dev_loopback_xmit(net, sk, skb); return dev_loopback_xmit(net, sk, skb);
} }

View File

@ -197,7 +197,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
} }
sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol, sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
iph->saddr, iph->daddr, iph->saddr, iph->daddr,
skb->dev->ifindex, sdif); dif, sdif);
} }
out: out:
read_unlock(&raw_v4_hashinfo.lock); read_unlock(&raw_v4_hashinfo.lock);

View File

@ -1647,6 +1647,39 @@ struct rtable *rt_dst_alloc(struct net_device *dev,
} }
EXPORT_SYMBOL(rt_dst_alloc); EXPORT_SYMBOL(rt_dst_alloc);
struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt)
{
struct rtable *new_rt;
new_rt = dst_alloc(&ipv4_dst_ops, dev, 1, DST_OBSOLETE_FORCE_CHK,
rt->dst.flags);
if (new_rt) {
new_rt->rt_genid = rt_genid_ipv4(dev_net(dev));
new_rt->rt_flags = rt->rt_flags;
new_rt->rt_type = rt->rt_type;
new_rt->rt_is_input = rt->rt_is_input;
new_rt->rt_iif = rt->rt_iif;
new_rt->rt_pmtu = rt->rt_pmtu;
new_rt->rt_mtu_locked = rt->rt_mtu_locked;
new_rt->rt_gw_family = rt->rt_gw_family;
if (rt->rt_gw_family == AF_INET)
new_rt->rt_gw4 = rt->rt_gw4;
else if (rt->rt_gw_family == AF_INET6)
new_rt->rt_gw6 = rt->rt_gw6;
INIT_LIST_HEAD(&new_rt->rt_uncached);
new_rt->dst.flags |= DST_HOST;
new_rt->dst.input = rt->dst.input;
new_rt->dst.output = rt->dst.output;
new_rt->dst.error = rt->dst.error;
new_rt->dst.lastuse = jiffies;
new_rt->dst.lwtstate = lwtstate_get(rt->dst.lwtstate);
}
return new_rt;
}
EXPORT_SYMBOL(rt_dst_clone);
/* called in rcu_read_lock() section */ /* called in rcu_read_lock() section */
int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr, int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev, u8 tos, struct net_device *dev,

View File

@ -59,8 +59,8 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
{ {
struct dst_entry *dst = skb_dst(skb); struct dst_entry *dst = skb_dst(skb);
struct net_device *dev = dst->dev; struct net_device *dev = dst->dev;
const struct in6_addr *nexthop;
struct neighbour *neigh; struct neighbour *neigh;
struct in6_addr *nexthop;
int ret; int ret;
if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) { if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {

View File

@ -218,7 +218,8 @@ static struct neighbour *ip6_dst_neigh_lookup(const struct dst_entry *dst,
{ {
const struct rt6_info *rt = container_of(dst, struct rt6_info, dst); const struct rt6_info *rt = container_of(dst, struct rt6_info, dst);
return ip6_neigh_lookup(&rt->rt6i_gateway, dst->dev, skb, daddr); return ip6_neigh_lookup(rt6_nexthop(rt, &in6addr_any),
dst->dev, skb, daddr);
} }
static void ip6_confirm_neigh(const struct dst_entry *dst, const void *daddr) static void ip6_confirm_neigh(const struct dst_entry *dst, const void *daddr)
@ -5281,7 +5282,7 @@ static struct ctl_table ipv6_route_table_template[] = {
.data = &init_net.ipv6.sysctl.skip_notify_on_dev_down, .data = &init_net.ipv6.sysctl.skip_notify_on_dev_down,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec_minmax,
.extra1 = &zero, .extra1 = &zero,
.extra2 = &one, .extra2 = &one,
}, },

View File

@ -439,9 +439,9 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
struct nf_flowtable *flow_table = priv; struct nf_flowtable *flow_table = priv;
struct flow_offload_tuple tuple = {}; struct flow_offload_tuple tuple = {};
enum flow_offload_tuple_dir dir; enum flow_offload_tuple_dir dir;
const struct in6_addr *nexthop;
struct flow_offload *flow; struct flow_offload *flow;
struct net_device *outdev; struct net_device *outdev;
struct in6_addr *nexthop;
struct ipv6hdr *ip6h; struct ipv6hdr *ip6h;
struct rt6_info *rt; struct rt6_info *rt;

View File

@ -2401,6 +2401,9 @@ static void tpacket_destruct_skb(struct sk_buff *skb)
ts = __packet_set_timestamp(po, ph, skb); ts = __packet_set_timestamp(po, ph, skb);
__packet_set_status(po, ph, TP_STATUS_AVAILABLE | ts); __packet_set_status(po, ph, TP_STATUS_AVAILABLE | ts);
if (!packet_read_pending(&po->tx_ring))
complete(&po->skb_completion);
} }
sock_wfree(skb); sock_wfree(skb);
@ -2585,7 +2588,7 @@ static int tpacket_parse_header(struct packet_sock *po, void *frame,
static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
{ {
struct sk_buff *skb; struct sk_buff *skb = NULL;
struct net_device *dev; struct net_device *dev;
struct virtio_net_hdr *vnet_hdr = NULL; struct virtio_net_hdr *vnet_hdr = NULL;
struct sockcm_cookie sockc; struct sockcm_cookie sockc;
@ -2600,6 +2603,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
int len_sum = 0; int len_sum = 0;
int status = TP_STATUS_AVAILABLE; int status = TP_STATUS_AVAILABLE;
int hlen, tlen, copylen = 0; int hlen, tlen, copylen = 0;
long timeo = 0;
mutex_lock(&po->pg_vec_lock); mutex_lock(&po->pg_vec_lock);
@ -2646,12 +2650,21 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
if ((size_max > dev->mtu + reserve + VLAN_HLEN) && !po->has_vnet_hdr) if ((size_max > dev->mtu + reserve + VLAN_HLEN) && !po->has_vnet_hdr)
size_max = dev->mtu + reserve + VLAN_HLEN; size_max = dev->mtu + reserve + VLAN_HLEN;
reinit_completion(&po->skb_completion);
do { do {
ph = packet_current_frame(po, &po->tx_ring, ph = packet_current_frame(po, &po->tx_ring,
TP_STATUS_SEND_REQUEST); TP_STATUS_SEND_REQUEST);
if (unlikely(ph == NULL)) { if (unlikely(ph == NULL)) {
if (need_wait && need_resched()) if (need_wait && skb) {
schedule(); timeo = sock_sndtimeo(&po->sk, msg->msg_flags & MSG_DONTWAIT);
timeo = wait_for_completion_interruptible_timeout(&po->skb_completion, timeo);
if (timeo <= 0) {
err = !timeo ? -ETIMEDOUT : -ERESTARTSYS;
goto out_put;
}
}
/* check for additional frames */
continue; continue;
} }
@ -3207,6 +3220,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
sock_init_data(sock, sk); sock_init_data(sock, sk);
po = pkt_sk(sk); po = pkt_sk(sk);
init_completion(&po->skb_completion);
sk->sk_family = PF_PACKET; sk->sk_family = PF_PACKET;
po->num = proto; po->num = proto;
po->xmit = dev_queue_xmit; po->xmit = dev_queue_xmit;
@ -4314,7 +4328,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
req3->tp_sizeof_priv || req3->tp_sizeof_priv ||
req3->tp_feature_req_word) { req3->tp_feature_req_word) {
err = -EINVAL; err = -EINVAL;
goto out; goto out_free_pg_vec;
} }
} }
break; break;
@ -4378,6 +4392,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
prb_shutdown_retire_blk_timer(po, rb_queue); prb_shutdown_retire_blk_timer(po, rb_queue);
} }
out_free_pg_vec:
if (pg_vec) if (pg_vec)
free_pg_vec(pg_vec, order, req->tp_block_nr); free_pg_vec(pg_vec, order, req->tp_block_nr);
out: out:

View File

@ -128,6 +128,7 @@ struct packet_sock {
unsigned int tp_hdrlen; unsigned int tp_hdrlen;
unsigned int tp_reserve; unsigned int tp_reserve;
unsigned int tp_tstamp; unsigned int tp_tstamp;
struct completion skb_completion;
struct net_device __rcu *cached_dev; struct net_device __rcu *cached_dev;
int (*xmit)(struct sk_buff *skb); int (*xmit)(struct sk_buff *skb);
struct packet_type prot_hook ____cacheline_aligned_in_smp; struct packet_type prot_hook ____cacheline_aligned_in_smp;

View File

@ -549,12 +549,17 @@ static struct notifier_block cbs_device_notifier = {
static int __init cbs_module_init(void) static int __init cbs_module_init(void)
{ {
int err = register_netdevice_notifier(&cbs_device_notifier); int err;
err = register_netdevice_notifier(&cbs_device_notifier);
if (err) if (err)
return err; return err;
return register_qdisc(&cbs_qdisc_ops); err = register_qdisc(&cbs_qdisc_ops);
if (err)
unregister_netdevice_notifier(&cbs_device_notifier);
return err;
} }
static void __exit cbs_module_exit(void) static void __exit cbs_module_exit(void)

View File

@ -118,10 +118,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
/* Initialize the bind addr area */ /* Initialize the bind addr area */
sctp_bind_addr_init(&ep->base.bind_addr, 0); sctp_bind_addr_init(&ep->base.bind_addr, 0);
/* Remember who we are attached to. */
ep->base.sk = sk;
sock_hold(ep->base.sk);
/* Create the lists of associations. */ /* Create the lists of associations. */
INIT_LIST_HEAD(&ep->asocs); INIT_LIST_HEAD(&ep->asocs);
@ -154,6 +150,10 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
ep->prsctp_enable = net->sctp.prsctp_enable; ep->prsctp_enable = net->sctp.prsctp_enable;
ep->reconf_enable = net->sctp.reconf_enable; ep->reconf_enable = net->sctp.reconf_enable;
/* Remember who we are attached to. */
ep->base.sk = sk;
sock_hold(ep->base.sk);
return ep; return ep;
nomem_shkey: nomem_shkey:

View File

@ -2029,7 +2029,7 @@ static int __init smc_init(void)
rc = smc_pnet_init(); rc = smc_pnet_init();
if (rc) if (rc)
return rc; goto out_pernet_subsys;
rc = smc_llc_init(); rc = smc_llc_init();
if (rc) { if (rc) {
@ -2080,6 +2080,9 @@ static int __init smc_init(void)
proto_unregister(&smc_proto); proto_unregister(&smc_proto);
out_pnet: out_pnet:
smc_pnet_exit(); smc_pnet_exit();
out_pernet_subsys:
unregister_pernet_subsys(&smc_net_ops);
return rc; return rc;
} }

View File

@ -652,7 +652,10 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
rc = smc_lgr_create(smc, ini); rc = smc_lgr_create(smc, ini);
if (rc) if (rc)
goto out; goto out;
lgr = conn->lgr;
write_lock_bh(&lgr->conns_lock);
smc_lgr_register_conn(conn); /* add smc conn to lgr */ smc_lgr_register_conn(conn); /* add smc conn to lgr */
write_unlock_bh(&lgr->conns_lock);
} }
conn->local_tx_ctrl.common.type = SMC_CDC_MSG_TYPE; conn->local_tx_ctrl.common.type = SMC_CDC_MSG_TYPE;
conn->local_tx_ctrl.len = SMC_WR_TX_SIZE; conn->local_tx_ctrl.len = SMC_WR_TX_SIZE;

View File

@ -134,7 +134,7 @@ static int __init tipc_init(void)
if (err) if (err)
goto out_sysctl; goto out_sysctl;
err = register_pernet_subsys(&tipc_net_ops); err = register_pernet_device(&tipc_net_ops);
if (err) if (err)
goto out_pernet; goto out_pernet;
@ -142,7 +142,7 @@ static int __init tipc_init(void)
if (err) if (err)
goto out_socket; goto out_socket;
err = register_pernet_subsys(&tipc_topsrv_net_ops); err = register_pernet_device(&tipc_topsrv_net_ops);
if (err) if (err)
goto out_pernet_topsrv; goto out_pernet_topsrv;
@ -153,11 +153,11 @@ static int __init tipc_init(void)
pr_info("Started in single node mode\n"); pr_info("Started in single node mode\n");
return 0; return 0;
out_bearer: out_bearer:
unregister_pernet_subsys(&tipc_topsrv_net_ops); unregister_pernet_device(&tipc_topsrv_net_ops);
out_pernet_topsrv: out_pernet_topsrv:
tipc_socket_stop(); tipc_socket_stop();
out_socket: out_socket:
unregister_pernet_subsys(&tipc_net_ops); unregister_pernet_device(&tipc_net_ops);
out_pernet: out_pernet:
tipc_unregister_sysctl(); tipc_unregister_sysctl();
out_sysctl: out_sysctl:
@ -172,9 +172,9 @@ static int __init tipc_init(void)
static void __exit tipc_exit(void) static void __exit tipc_exit(void)
{ {
tipc_bearer_cleanup(); tipc_bearer_cleanup();
unregister_pernet_subsys(&tipc_topsrv_net_ops); unregister_pernet_device(&tipc_topsrv_net_ops);
tipc_socket_stop(); tipc_socket_stop();
unregister_pernet_subsys(&tipc_net_ops); unregister_pernet_device(&tipc_net_ops);
tipc_netlink_stop(); tipc_netlink_stop();
tipc_netlink_compat_stop(); tipc_netlink_compat_stop();
tipc_unregister_sysctl(); tipc_unregister_sysctl();

View File

@ -445,7 +445,11 @@ static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd,
if (!bearer) if (!bearer)
return -EMSGSIZE; return -EMSGSIZE;
len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME); len = TLV_GET_DATA_LEN(msg->req);
if (len <= 0)
return -EINVAL;
len = min_t(int, len, TIPC_MAX_BEARER_NAME);
if (!string_is_valid(name, len)) if (!string_is_valid(name, len))
return -EINVAL; return -EINVAL;
@ -539,7 +543,11 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg,
name = (char *)TLV_DATA(msg->req); name = (char *)TLV_DATA(msg->req);
len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME); len = TLV_GET_DATA_LEN(msg->req);
if (len <= 0)
return -EINVAL;
len = min_t(int, len, TIPC_MAX_BEARER_NAME);
if (!string_is_valid(name, len)) if (!string_is_valid(name, len))
return -EINVAL; return -EINVAL;
@ -817,7 +825,11 @@ static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd,
if (!link) if (!link)
return -EMSGSIZE; return -EMSGSIZE;
len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME); len = TLV_GET_DATA_LEN(msg->req);
if (len <= 0)
return -EINVAL;
len = min_t(int, len, TIPC_MAX_BEARER_NAME);
if (!string_is_valid(name, len)) if (!string_is_valid(name, len))
return -EINVAL; return -EINVAL;

View File

@ -279,7 +279,8 @@ static void tls_sk_proto_close(struct sock *sk, long timeout)
goto skip_tx_cleanup; goto skip_tx_cleanup;
} }
if (!tls_complete_pending_work(sk, ctx, 0, &timeo)) if (unlikely(sk->sk_write_pending) &&
!wait_on_pending_writer(sk, &timeo))
tls_handle_open_record(sk, 0); tls_handle_open_record(sk, 0);
/* We need these for tls_sw_fallback handling of other packets */ /* We need these for tls_sw_fallback handling of other packets */