diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-12 14:09:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-12 14:09:05 -0400 |
commit | 5d1365940a68dd57b031b6e3c07d7d451cd69daf (patch) | |
tree | 1d94923756eb792f54cfde22495980c5d3977b0c | |
parent | 67a7a8fff8aef69579cd4426dca1ccb865b93167 (diff) | |
parent | 0c84cee8f131a090f77f5a3dea5d6a7bd99c00db (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
1) In ip_gre tunnel, handle the conflict between TUNNEL_{SEQ,CSUM} and
GSO/LLTX properly. From Sabrina Dubroca.
2) Stop properly on error in lan78xx_read_otp(), from Phil Elwell.
3) Don't uncompress in slip before rstate is initialized, from Tejaswi
Tanikella.
4) When using 1.x firmware on aquantia, issue a deinit before we
hardware reset the chip, otherwise we break dirty wake WOL. From
Igor Russkikh.
5) Correct log check in vhost_vq_access_ok(), from Stefan Hajnoczi.
6) Fix ethtool -x crashes in bnxt_en, from Michael Chan.
7) Fix races in l2tp tunnel creation and duplicate tunnel detection,
from Guillaume Nault.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (22 commits)
l2tp: fix race in duplicate tunnel detection
l2tp: fix races in tunnel creation
tun: send netlink notification when the device is modified
tun: set the flags before registering the netdevice
lan78xx: Don't reset the interface on open
bnxt_en: Fix NULL pointer dereference at bnxt_free_irq().
bnxt_en: Need to include RDMA rings in bnxt_check_rings().
bnxt_en: Support max-mtu with VF-reps
bnxt_en: Ignore src port field in decap filter nodes
bnxt_en: do not allow wildcard matches for L2 flows
bnxt_en: Fix ethtool -x crash when device is down.
vhost: return bool from *_access_ok() functions
vhost: fix vhost_vq_access_ok() log check
vhost: Fix vhost_copy_to_user()
net: aquantia: oops when shutdown on already stopped device
net: aquantia: Regression on reset with 1.x firmware
cdc_ether: flag the Cinterion AHS8 modem by gemalto as WWAN
slip: Check if rstate is initialized before uncompressing
lan78xx: Avoid spurious kevent 4 "error"
lan78xx: Correctly indicate invalid OTP
...
-rw-r--r-- | drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | 63 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 30 | ||||
-rw-r--r-- | drivers/net/slip/slhc.c | 5 | ||||
-rw-r--r-- | drivers/net/tun.c | 33 | ||||
-rw-r--r-- | drivers/net/usb/cdc_ether.c | 6 | ||||
-rw-r--r-- | drivers/net/usb/lan78xx.c | 9 | ||||
-rw-r--r-- | drivers/vhost/vhost.c | 72 | ||||
-rw-r--r-- | drivers/vhost/vhost.h | 4 | ||||
-rw-r--r-- | include/net/slhc_vj.h | 1 | ||||
-rw-r--r-- | net/ipv4/ip_gre.c | 6 | ||||
-rw-r--r-- | net/l2tp/l2tp_core.c | 225 | ||||
-rw-r--r-- | net/l2tp/l2tp_core.h | 4 | ||||
-rw-r--r-- | net/l2tp/l2tp_netlink.c | 22 | ||||
-rw-r--r-- | net/l2tp/l2tp_ppp.c | 9 | ||||
-rw-r--r-- | net/rds/send.c | 15 |
19 files changed, 345 insertions, 198 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index c96a92118b8b..32f6d2e24d66 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c | |||
@@ -951,9 +951,11 @@ void aq_nic_shutdown(struct aq_nic_s *self) | |||
951 | 951 | ||
952 | netif_device_detach(self->ndev); | 952 | netif_device_detach(self->ndev); |
953 | 953 | ||
954 | err = aq_nic_stop(self); | 954 | if (netif_running(self->ndev)) { |
955 | if (err < 0) | 955 | err = aq_nic_stop(self); |
956 | goto err_exit; | 956 | if (err < 0) |
957 | goto err_exit; | ||
958 | } | ||
957 | aq_nic_deinit(self); | 959 | aq_nic_deinit(self); |
958 | 960 | ||
959 | err_exit: | 961 | err_exit: |
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c index 84d7f4dd4ce1..e652d86b87d4 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | |||
@@ -48,6 +48,8 @@ | |||
48 | #define FORCE_FLASHLESS 0 | 48 | #define FORCE_FLASHLESS 0 |
49 | 49 | ||
50 | static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual); | 50 | static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual); |
51 | static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self, | ||
52 | enum hal_atl_utils_fw_state_e state); | ||
51 | 53 | ||
52 | int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops) | 54 | int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops) |
53 | { | 55 | { |
@@ -247,6 +249,20 @@ int hw_atl_utils_soft_reset(struct aq_hw_s *self) | |||
247 | 249 | ||
248 | self->rbl_enabled = (boot_exit_code != 0); | 250 | self->rbl_enabled = (boot_exit_code != 0); |
249 | 251 | ||
252 | /* FW 1.x may bootup in an invalid POWER state (WOL feature). | ||
253 | * We should work around this by forcing its state back to DEINIT | ||
254 | */ | ||
255 | if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, | ||
256 | aq_hw_read_reg(self, | ||
257 | HW_ATL_MPI_FW_VERSION))) { | ||
258 | int err = 0; | ||
259 | |||
260 | hw_atl_utils_mpi_set_state(self, MPI_DEINIT); | ||
261 | AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) & | ||
262 | HW_ATL_MPI_STATE_MSK) == MPI_DEINIT, | ||
263 | 10, 1000U); | ||
264 | } | ||
265 | |||
250 | if (self->rbl_enabled) | 266 | if (self->rbl_enabled) |
251 | return hw_atl_utils_soft_reset_rbl(self); | 267 | return hw_atl_utils_soft_reset_rbl(self); |
252 | else | 268 | else |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 1991f0c7bc0e..f83769d8047b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -6090,7 +6090,7 @@ static void bnxt_free_irq(struct bnxt *bp) | |||
6090 | free_irq_cpu_rmap(bp->dev->rx_cpu_rmap); | 6090 | free_irq_cpu_rmap(bp->dev->rx_cpu_rmap); |
6091 | bp->dev->rx_cpu_rmap = NULL; | 6091 | bp->dev->rx_cpu_rmap = NULL; |
6092 | #endif | 6092 | #endif |
6093 | if (!bp->irq_tbl) | 6093 | if (!bp->irq_tbl || !bp->bnapi) |
6094 | return; | 6094 | return; |
6095 | 6095 | ||
6096 | for (i = 0; i < bp->cp_nr_rings; i++) { | 6096 | for (i = 0; i < bp->cp_nr_rings; i++) { |
@@ -7686,6 +7686,8 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs, | |||
7686 | if (bp->flags & BNXT_FLAG_AGG_RINGS) | 7686 | if (bp->flags & BNXT_FLAG_AGG_RINGS) |
7687 | rx_rings <<= 1; | 7687 | rx_rings <<= 1; |
7688 | cp = sh ? max_t(int, tx_rings_needed, rx) : tx_rings_needed + rx; | 7688 | cp = sh ? max_t(int, tx_rings_needed, rx) : tx_rings_needed + rx; |
7689 | if (bp->flags & BNXT_FLAG_NEW_RM) | ||
7690 | cp += bnxt_get_ulp_msix_num(bp); | ||
7689 | return bnxt_hwrm_check_rings(bp, tx_rings_needed, rx_rings, rx, cp, | 7691 | return bnxt_hwrm_check_rings(bp, tx_rings_needed, rx_rings, rx, cp, |
7690 | vnics); | 7692 | vnics); |
7691 | } | 7693 | } |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 8d8ccd67e0e2..1f622ca2a64f 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | |||
@@ -870,17 +870,22 @@ static int bnxt_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, | |||
870 | u8 *hfunc) | 870 | u8 *hfunc) |
871 | { | 871 | { |
872 | struct bnxt *bp = netdev_priv(dev); | 872 | struct bnxt *bp = netdev_priv(dev); |
873 | struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; | 873 | struct bnxt_vnic_info *vnic; |
874 | int i = 0; | 874 | int i = 0; |
875 | 875 | ||
876 | if (hfunc) | 876 | if (hfunc) |
877 | *hfunc = ETH_RSS_HASH_TOP; | 877 | *hfunc = ETH_RSS_HASH_TOP; |
878 | 878 | ||
879 | if (indir) | 879 | if (!bp->vnic_info) |
880 | return 0; | ||
881 | |||
882 | vnic = &bp->vnic_info[0]; | ||
883 | if (indir && vnic->rss_table) { | ||
880 | for (i = 0; i < HW_HASH_INDEX_SIZE; i++) | 884 | for (i = 0; i < HW_HASH_INDEX_SIZE; i++) |
881 | indir[i] = le16_to_cpu(vnic->rss_table[i]); | 885 | indir[i] = le16_to_cpu(vnic->rss_table[i]); |
886 | } | ||
882 | 887 | ||
883 | if (key) | 888 | if (key && vnic->rss_hash_key) |
884 | memcpy(key, vnic->rss_hash_key, HW_HASH_KEY_SIZE); | 889 | memcpy(key, vnic->rss_hash_key, HW_HASH_KEY_SIZE); |
885 | 890 | ||
886 | return 0; | 891 | return 0; |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c index 65c2cee35766..795f45024c20 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | |||
@@ -377,6 +377,30 @@ static bool is_wildcard(void *mask, int len) | |||
377 | return true; | 377 | return true; |
378 | } | 378 | } |
379 | 379 | ||
380 | static bool is_exactmatch(void *mask, int len) | ||
381 | { | ||
382 | const u8 *p = mask; | ||
383 | int i; | ||
384 | |||
385 | for (i = 0; i < len; i++) | ||
386 | if (p[i] != 0xff) | ||
387 | return false; | ||
388 | |||
389 | return true; | ||
390 | } | ||
391 | |||
392 | static bool bits_set(void *key, int len) | ||
393 | { | ||
394 | const u8 *p = key; | ||
395 | int i; | ||
396 | |||
397 | for (i = 0; i < len; i++) | ||
398 | if (p[i] != 0) | ||
399 | return true; | ||
400 | |||
401 | return false; | ||
402 | } | ||
403 | |||
380 | static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, | 404 | static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, |
381 | __le16 ref_flow_handle, | 405 | __le16 ref_flow_handle, |
382 | __le32 tunnel_handle, __le16 *flow_handle) | 406 | __le32 tunnel_handle, __le16 *flow_handle) |
@@ -764,6 +788,41 @@ static bool bnxt_tc_can_offload(struct bnxt *bp, struct bnxt_tc_flow *flow) | |||
764 | return false; | 788 | return false; |
765 | } | 789 | } |
766 | 790 | ||
791 | /* Currently source/dest MAC cannot be partial wildcard */ | ||
792 | if (bits_set(&flow->l2_key.smac, sizeof(flow->l2_key.smac)) && | ||
793 | !is_exactmatch(flow->l2_mask.smac, sizeof(flow->l2_mask.smac))) { | ||
794 | netdev_info(bp->dev, "Wildcard match unsupported for Source MAC\n"); | ||
795 | return false; | ||
796 | } | ||
797 | if (bits_set(&flow->l2_key.dmac, sizeof(flow->l2_key.dmac)) && | ||
798 | !is_exactmatch(&flow->l2_mask.dmac, sizeof(flow->l2_mask.dmac))) { | ||
799 | netdev_info(bp->dev, "Wildcard match unsupported for Dest MAC\n"); | ||
800 | return false; | ||
801 | } | ||
802 | |||
803 | /* Currently VLAN fields cannot be partial wildcard */ | ||
804 | if (bits_set(&flow->l2_key.inner_vlan_tci, | ||
805 | sizeof(flow->l2_key.inner_vlan_tci)) && | ||
806 | !is_exactmatch(&flow->l2_mask.inner_vlan_tci, | ||
807 | sizeof(flow->l2_mask.inner_vlan_tci))) { | ||
808 | netdev_info(bp->dev, "Wildcard match unsupported for VLAN TCI\n"); | ||
809 | return false; | ||
810 | } | ||
811 | if (bits_set(&flow->l2_key.inner_vlan_tpid, | ||
812 | sizeof(flow->l2_key.inner_vlan_tpid)) && | ||
813 | !is_exactmatch(&flow->l2_mask.inner_vlan_tpid, | ||
814 | sizeof(flow->l2_mask.inner_vlan_tpid))) { | ||
815 | netdev_info(bp->dev, "Wildcard match unsupported for VLAN TPID\n"); | ||
816 | return false; | ||
817 | } | ||
818 | |||
819 | /* Currently Ethertype must be set */ | ||
820 | if (!is_exactmatch(&flow->l2_mask.ether_type, | ||
821 | sizeof(flow->l2_mask.ether_type))) { | ||
822 | netdev_info(bp->dev, "Wildcard match unsupported for Ethertype\n"); | ||
823 | return false; | ||
824 | } | ||
825 | |||
767 | return true; | 826 | return true; |
768 | } | 827 | } |
769 | 828 | ||
@@ -992,8 +1051,10 @@ static int bnxt_tc_get_decap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, | |||
992 | 1051 | ||
993 | /* Check if there's another flow using the same tunnel decap. | 1052 | /* Check if there's another flow using the same tunnel decap. |
994 | * If not, add this tunnel to the table and resolve the other | 1053 | * If not, add this tunnel to the table and resolve the other |
995 | * tunnel header fileds | 1054 | * tunnel header fileds. Ignore src_port in the tunnel_key, |
1055 | * since it is not required for decap filters. | ||
996 | */ | 1056 | */ |
1057 | decap_key->tp_src = 0; | ||
997 | decap_node = bnxt_tc_get_tunnel_node(bp, &tc_info->decap_table, | 1058 | decap_node = bnxt_tc_get_tunnel_node(bp, &tc_info->decap_table, |
998 | &tc_info->decap_ht_params, | 1059 | &tc_info->decap_ht_params, |
999 | decap_key); | 1060 | decap_key); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c index 26290403f38f..38f635cf8408 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | |||
@@ -64,6 +64,31 @@ static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx) | |||
64 | return rc; | 64 | return rc; |
65 | } | 65 | } |
66 | 66 | ||
67 | static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, | ||
68 | u16 *max_mtu) | ||
69 | { | ||
70 | struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr; | ||
71 | struct hwrm_func_qcfg_input req = {0}; | ||
72 | u16 mtu; | ||
73 | int rc; | ||
74 | |||
75 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_QCFG, -1, -1); | ||
76 | req.fid = cpu_to_le16(bp->pf.vf[vf_rep->vf_idx].fw_fid); | ||
77 | |||
78 | mutex_lock(&bp->hwrm_cmd_lock); | ||
79 | |||
80 | rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | ||
81 | if (!rc) { | ||
82 | mtu = le16_to_cpu(resp->max_mtu_configured); | ||
83 | if (!mtu) | ||
84 | *max_mtu = BNXT_MAX_MTU; | ||
85 | else | ||
86 | *max_mtu = mtu; | ||
87 | } | ||
88 | mutex_unlock(&bp->hwrm_cmd_lock); | ||
89 | return rc; | ||
90 | } | ||
91 | |||
67 | static int bnxt_vf_rep_open(struct net_device *dev) | 92 | static int bnxt_vf_rep_open(struct net_device *dev) |
68 | { | 93 | { |
69 | struct bnxt_vf_rep *vf_rep = netdev_priv(dev); | 94 | struct bnxt_vf_rep *vf_rep = netdev_priv(dev); |
@@ -365,6 +390,7 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, | |||
365 | struct net_device *dev) | 390 | struct net_device *dev) |
366 | { | 391 | { |
367 | struct net_device *pf_dev = bp->dev; | 392 | struct net_device *pf_dev = bp->dev; |
393 | u16 max_mtu; | ||
368 | 394 | ||
369 | dev->netdev_ops = &bnxt_vf_rep_netdev_ops; | 395 | dev->netdev_ops = &bnxt_vf_rep_netdev_ops; |
370 | dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops; | 396 | dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops; |
@@ -380,6 +406,10 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, | |||
380 | bnxt_vf_rep_eth_addr_gen(bp->pf.mac_addr, vf_rep->vf_idx, | 406 | bnxt_vf_rep_eth_addr_gen(bp->pf.mac_addr, vf_rep->vf_idx, |
381 | dev->perm_addr); | 407 | dev->perm_addr); |
382 | ether_addr_copy(dev->dev_addr, dev->perm_addr); | 408 | ether_addr_copy(dev->dev_addr, dev->perm_addr); |
409 | /* Set VF-Rep's max-mtu to the corresponding VF's max-mtu */ | ||
410 | if (!bnxt_hwrm_vfr_qcfg(bp, vf_rep, &max_mtu)) | ||
411 | dev->max_mtu = max_mtu; | ||
412 | dev->min_mtu = ETH_ZLEN; | ||
383 | } | 413 | } |
384 | 414 | ||
385 | static int bnxt_pcie_dsn_get(struct bnxt *bp, u8 dsn[]) | 415 | static int bnxt_pcie_dsn_get(struct bnxt *bp, u8 dsn[]) |
diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c index 5782733959f0..f4e93f5fc204 100644 --- a/drivers/net/slip/slhc.c +++ b/drivers/net/slip/slhc.c | |||
@@ -509,6 +509,10 @@ slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) | |||
509 | if(x < 0 || x > comp->rslot_limit) | 509 | if(x < 0 || x > comp->rslot_limit) |
510 | goto bad; | 510 | goto bad; |
511 | 511 | ||
512 | /* Check if the cstate is initialized */ | ||
513 | if (!comp->rstate[x].initialized) | ||
514 | goto bad; | ||
515 | |||
512 | comp->flags &=~ SLF_TOSS; | 516 | comp->flags &=~ SLF_TOSS; |
513 | comp->recv_current = x; | 517 | comp->recv_current = x; |
514 | } else { | 518 | } else { |
@@ -673,6 +677,7 @@ slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) | |||
673 | if (cs->cs_tcp.doff > 5) | 677 | if (cs->cs_tcp.doff > 5) |
674 | memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); | 678 | memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); |
675 | cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; | 679 | cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; |
680 | cs->initialized = true; | ||
676 | /* Put headers back on packet | 681 | /* Put headers back on packet |
677 | * Neither header checksum is recalculated | 682 | * Neither header checksum is recalculated |
678 | */ | 683 | */ |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a1ba262f40ad..28583aa0c17d 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -743,8 +743,15 @@ static void __tun_detach(struct tun_file *tfile, bool clean) | |||
743 | 743 | ||
744 | static void tun_detach(struct tun_file *tfile, bool clean) | 744 | static void tun_detach(struct tun_file *tfile, bool clean) |
745 | { | 745 | { |
746 | struct tun_struct *tun; | ||
747 | struct net_device *dev; | ||
748 | |||
746 | rtnl_lock(); | 749 | rtnl_lock(); |
750 | tun = rtnl_dereference(tfile->tun); | ||
751 | dev = tun ? tun->dev : NULL; | ||
747 | __tun_detach(tfile, clean); | 752 | __tun_detach(tfile, clean); |
753 | if (dev) | ||
754 | netdev_state_change(dev); | ||
748 | rtnl_unlock(); | 755 | rtnl_unlock(); |
749 | } | 756 | } |
750 | 757 | ||
@@ -2562,10 +2569,15 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
2562 | /* One or more queue has already been attached, no need | 2569 | /* One or more queue has already been attached, no need |
2563 | * to initialize the device again. | 2570 | * to initialize the device again. |
2564 | */ | 2571 | */ |
2572 | netdev_state_change(dev); | ||
2565 | return 0; | 2573 | return 0; |
2566 | } | 2574 | } |
2567 | } | 2575 | |
2568 | else { | 2576 | tun->flags = (tun->flags & ~TUN_FEATURES) | |
2577 | (ifr->ifr_flags & TUN_FEATURES); | ||
2578 | |||
2579 | netdev_state_change(dev); | ||
2580 | } else { | ||
2569 | char *name; | 2581 | char *name; |
2570 | unsigned long flags = 0; | 2582 | unsigned long flags = 0; |
2571 | int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ? | 2583 | int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ? |
@@ -2642,6 +2654,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
2642 | ~(NETIF_F_HW_VLAN_CTAG_TX | | 2654 | ~(NETIF_F_HW_VLAN_CTAG_TX | |
2643 | NETIF_F_HW_VLAN_STAG_TX); | 2655 | NETIF_F_HW_VLAN_STAG_TX); |
2644 | 2656 | ||
2657 | tun->flags = (tun->flags & ~TUN_FEATURES) | | ||
2658 | (ifr->ifr_flags & TUN_FEATURES); | ||
2659 | |||
2645 | INIT_LIST_HEAD(&tun->disabled); | 2660 | INIT_LIST_HEAD(&tun->disabled); |
2646 | err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI); | 2661 | err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI); |
2647 | if (err < 0) | 2662 | if (err < 0) |
@@ -2656,9 +2671,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
2656 | 2671 | ||
2657 | tun_debug(KERN_INFO, tun, "tun_set_iff\n"); | 2672 | tun_debug(KERN_INFO, tun, "tun_set_iff\n"); |
2658 | 2673 | ||
2659 | tun->flags = (tun->flags & ~TUN_FEATURES) | | ||
2660 | (ifr->ifr_flags & TUN_FEATURES); | ||
2661 | |||
2662 | /* Make sure persistent devices do not get stuck in | 2674 | /* Make sure persistent devices do not get stuck in |
2663 | * xoff state. | 2675 | * xoff state. |
2664 | */ | 2676 | */ |
@@ -2805,6 +2817,9 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) | |||
2805 | } else | 2817 | } else |
2806 | ret = -EINVAL; | 2818 | ret = -EINVAL; |
2807 | 2819 | ||
2820 | if (ret >= 0) | ||
2821 | netdev_state_change(tun->dev); | ||
2822 | |||
2808 | unlock: | 2823 | unlock: |
2809 | rtnl_unlock(); | 2824 | rtnl_unlock(); |
2810 | return ret; | 2825 | return ret; |
@@ -2845,6 +2860,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
2845 | unsigned int ifindex; | 2860 | unsigned int ifindex; |
2846 | int le; | 2861 | int le; |
2847 | int ret; | 2862 | int ret; |
2863 | bool do_notify = false; | ||
2848 | 2864 | ||
2849 | if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || | 2865 | if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || |
2850 | (_IOC_TYPE(cmd) == SOCK_IOC_TYPE && cmd != SIOCGSKNS)) { | 2866 | (_IOC_TYPE(cmd) == SOCK_IOC_TYPE && cmd != SIOCGSKNS)) { |
@@ -2941,10 +2957,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
2941 | if (arg && !(tun->flags & IFF_PERSIST)) { | 2957 | if (arg && !(tun->flags & IFF_PERSIST)) { |
2942 | tun->flags |= IFF_PERSIST; | 2958 | tun->flags |= IFF_PERSIST; |
2943 | __module_get(THIS_MODULE); | 2959 | __module_get(THIS_MODULE); |
2960 | do_notify = true; | ||
2944 | } | 2961 | } |
2945 | if (!arg && (tun->flags & IFF_PERSIST)) { | 2962 | if (!arg && (tun->flags & IFF_PERSIST)) { |
2946 | tun->flags &= ~IFF_PERSIST; | 2963 | tun->flags &= ~IFF_PERSIST; |
2947 | module_put(THIS_MODULE); | 2964 | module_put(THIS_MODULE); |
2965 | do_notify = true; | ||
2948 | } | 2966 | } |
2949 | 2967 | ||
2950 | tun_debug(KERN_INFO, tun, "persist %s\n", | 2968 | tun_debug(KERN_INFO, tun, "persist %s\n", |
@@ -2959,6 +2977,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
2959 | break; | 2977 | break; |
2960 | } | 2978 | } |
2961 | tun->owner = owner; | 2979 | tun->owner = owner; |
2980 | do_notify = true; | ||
2962 | tun_debug(KERN_INFO, tun, "owner set to %u\n", | 2981 | tun_debug(KERN_INFO, tun, "owner set to %u\n", |
2963 | from_kuid(&init_user_ns, tun->owner)); | 2982 | from_kuid(&init_user_ns, tun->owner)); |
2964 | break; | 2983 | break; |
@@ -2971,6 +2990,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
2971 | break; | 2990 | break; |
2972 | } | 2991 | } |
2973 | tun->group = group; | 2992 | tun->group = group; |
2993 | do_notify = true; | ||
2974 | tun_debug(KERN_INFO, tun, "group set to %u\n", | 2994 | tun_debug(KERN_INFO, tun, "group set to %u\n", |
2975 | from_kgid(&init_user_ns, tun->group)); | 2995 | from_kgid(&init_user_ns, tun->group)); |
2976 | break; | 2996 | break; |
@@ -3130,6 +3150,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
3130 | break; | 3150 | break; |
3131 | } | 3151 | } |
3132 | 3152 | ||
3153 | if (do_notify) | ||
3154 | netdev_state_change(tun->dev); | ||
3155 | |||
3133 | unlock: | 3156 | unlock: |
3134 | rtnl_unlock(); | 3157 | rtnl_unlock(); |
3135 | if (tun) | 3158 | if (tun) |
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index fff4b13eece2..5c42cf81a08b 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
@@ -902,6 +902,12 @@ static const struct usb_device_id products[] = { | |||
902 | USB_CDC_PROTO_NONE), | 902 | USB_CDC_PROTO_NONE), |
903 | .driver_info = (unsigned long)&wwan_info, | 903 | .driver_info = (unsigned long)&wwan_info, |
904 | }, { | 904 | }, { |
905 | /* Cinterion AHS3 modem by GEMALTO */ | ||
906 | USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x0055, USB_CLASS_COMM, | ||
907 | USB_CDC_SUBCLASS_ETHERNET, | ||
908 | USB_CDC_PROTO_NONE), | ||
909 | .driver_info = (unsigned long)&wwan_info, | ||
910 | }, { | ||
905 | USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, | 911 | USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, |
906 | USB_CDC_PROTO_NONE), | 912 | USB_CDC_PROTO_NONE), |
907 | .driver_info = (unsigned long) &cdc_info, | 913 | .driver_info = (unsigned long) &cdc_info, |
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index aff105f5f58c..0867f7275852 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c | |||
@@ -928,7 +928,8 @@ static int lan78xx_read_otp(struct lan78xx_net *dev, u32 offset, | |||
928 | offset += 0x100; | 928 | offset += 0x100; |
929 | else | 929 | else |
930 | ret = -EINVAL; | 930 | ret = -EINVAL; |
931 | ret = lan78xx_read_raw_otp(dev, offset, length, data); | 931 | if (!ret) |
932 | ret = lan78xx_read_raw_otp(dev, offset, length, data); | ||
932 | } | 933 | } |
933 | 934 | ||
934 | return ret; | 935 | return ret; |
@@ -2502,7 +2503,7 @@ static void lan78xx_init_stats(struct lan78xx_net *dev) | |||
2502 | dev->stats.rollover_max.eee_tx_lpi_transitions = 0xFFFFFFFF; | 2503 | dev->stats.rollover_max.eee_tx_lpi_transitions = 0xFFFFFFFF; |
2503 | dev->stats.rollover_max.eee_tx_lpi_time = 0xFFFFFFFF; | 2504 | dev->stats.rollover_max.eee_tx_lpi_time = 0xFFFFFFFF; |
2504 | 2505 | ||
2505 | lan78xx_defer_kevent(dev, EVENT_STAT_UPDATE); | 2506 | set_bit(EVENT_STAT_UPDATE, &dev->flags); |
2506 | } | 2507 | } |
2507 | 2508 | ||
2508 | static int lan78xx_open(struct net_device *net) | 2509 | static int lan78xx_open(struct net_device *net) |
@@ -2514,10 +2515,6 @@ static int lan78xx_open(struct net_device *net) | |||
2514 | if (ret < 0) | 2515 | if (ret < 0) |
2515 | goto out; | 2516 | goto out; |
2516 | 2517 | ||
2517 | ret = lan78xx_reset(dev); | ||
2518 | if (ret < 0) | ||
2519 | goto done; | ||
2520 | |||
2521 | phy_start(net->phydev); | 2518 | phy_start(net->phydev); |
2522 | 2519 | ||
2523 | netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); | 2520 | netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index bec722e41f58..f3bd8e941224 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -641,14 +641,14 @@ void vhost_dev_cleanup(struct vhost_dev *dev) | |||
641 | } | 641 | } |
642 | EXPORT_SYMBOL_GPL(vhost_dev_cleanup); | 642 | EXPORT_SYMBOL_GPL(vhost_dev_cleanup); |
643 | 643 | ||
644 | static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) | 644 | static bool log_access_ok(void __user *log_base, u64 addr, unsigned long sz) |
645 | { | 645 | { |
646 | u64 a = addr / VHOST_PAGE_SIZE / 8; | 646 | u64 a = addr / VHOST_PAGE_SIZE / 8; |
647 | 647 | ||
648 | /* Make sure 64 bit math will not overflow. */ | 648 | /* Make sure 64 bit math will not overflow. */ |
649 | if (a > ULONG_MAX - (unsigned long)log_base || | 649 | if (a > ULONG_MAX - (unsigned long)log_base || |
650 | a + (unsigned long)log_base > ULONG_MAX) | 650 | a + (unsigned long)log_base > ULONG_MAX) |
651 | return 0; | 651 | return false; |
652 | 652 | ||
653 | return access_ok(VERIFY_WRITE, log_base + a, | 653 | return access_ok(VERIFY_WRITE, log_base + a, |
654 | (sz + VHOST_PAGE_SIZE * 8 - 1) / VHOST_PAGE_SIZE / 8); | 654 | (sz + VHOST_PAGE_SIZE * 8 - 1) / VHOST_PAGE_SIZE / 8); |
@@ -661,30 +661,30 @@ static bool vhost_overflow(u64 uaddr, u64 size) | |||
661 | } | 661 | } |
662 | 662 | ||
663 | /* Caller should have vq mutex and device mutex. */ | 663 | /* Caller should have vq mutex and device mutex. */ |
664 | static int vq_memory_access_ok(void __user *log_base, struct vhost_umem *umem, | 664 | static bool vq_memory_access_ok(void __user *log_base, struct vhost_umem *umem, |
665 | int log_all) | 665 | int log_all) |
666 | { | 666 | { |
667 | struct vhost_umem_node *node; | 667 | struct vhost_umem_node *node; |
668 | 668 | ||
669 | if (!umem) | 669 | if (!umem) |
670 | return 0; | 670 | return false; |
671 | 671 | ||
672 | list_for_each_entry(node, &umem->umem_list, link) { | 672 | list_for_each_entry(node, &umem->umem_list, link) { |
673 | unsigned long a = node->userspace_addr; | 673 | unsigned long a = node->userspace_addr; |
674 | 674 | ||
675 | if (vhost_overflow(node->userspace_addr, node->size)) | 675 | if (vhost_overflow(node->userspace_addr, node->size)) |
676 | return 0; | 676 | return false; |
677 | 677 | ||
678 | 678 | ||
679 | if (!access_ok(VERIFY_WRITE, (void __user *)a, | 679 | if (!access_ok(VERIFY_WRITE, (void __user *)a, |
680 | node->size)) | 680 | node->size)) |
681 | return 0; | 681 | return false; |
682 | else if (log_all && !log_access_ok(log_base, | 682 | else if (log_all && !log_access_ok(log_base, |
683 | node->start, | 683 | node->start, |
684 | node->size)) | 684 | node->size)) |
685 | return 0; | 685 | return false; |
686 | } | 686 | } |
687 | return 1; | 687 | return true; |
688 | } | 688 | } |
689 | 689 | ||
690 | static inline void __user *vhost_vq_meta_fetch(struct vhost_virtqueue *vq, | 690 | static inline void __user *vhost_vq_meta_fetch(struct vhost_virtqueue *vq, |
@@ -701,13 +701,13 @@ static inline void __user *vhost_vq_meta_fetch(struct vhost_virtqueue *vq, | |||
701 | 701 | ||
702 | /* Can we switch to this memory table? */ | 702 | /* Can we switch to this memory table? */ |
703 | /* Caller should have device mutex but not vq mutex */ | 703 | /* Caller should have device mutex but not vq mutex */ |
704 | static int memory_access_ok(struct vhost_dev *d, struct vhost_umem *umem, | 704 | static bool memory_access_ok(struct vhost_dev *d, struct vhost_umem *umem, |
705 | int log_all) | 705 | int log_all) |
706 | { | 706 | { |
707 | int i; | 707 | int i; |
708 | 708 | ||
709 | for (i = 0; i < d->nvqs; ++i) { | 709 | for (i = 0; i < d->nvqs; ++i) { |
710 | int ok; | 710 | bool ok; |
711 | bool log; | 711 | bool log; |
712 | 712 | ||
713 | mutex_lock(&d->vqs[i]->mutex); | 713 | mutex_lock(&d->vqs[i]->mutex); |
@@ -717,12 +717,12 @@ static int memory_access_ok(struct vhost_dev *d, struct vhost_umem *umem, | |||
717 | ok = vq_memory_access_ok(d->vqs[i]->log_base, | 717 | ok = vq_memory_access_ok(d->vqs[i]->log_base, |
718 | umem, log); | 718 | umem, log); |
719 | else | 719 | else |
720 | ok = 1; | 720 | ok = true; |
721 | mutex_unlock(&d->vqs[i]->mutex); | 721 | mutex_unlock(&d->vqs[i]->mutex); |
722 | if (!ok) | 722 | if (!ok) |
723 | return 0; | 723 | return false; |
724 | } | 724 | } |
725 | return 1; | 725 | return true; |
726 | } | 726 | } |
727 | 727 | ||
728 | static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len, | 728 | static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len, |
@@ -744,7 +744,7 @@ static int vhost_copy_to_user(struct vhost_virtqueue *vq, void __user *to, | |||
744 | struct iov_iter t; | 744 | struct iov_iter t; |
745 | void __user *uaddr = vhost_vq_meta_fetch(vq, | 745 | void __user *uaddr = vhost_vq_meta_fetch(vq, |
746 | (u64)(uintptr_t)to, size, | 746 | (u64)(uintptr_t)to, size, |
747 | VHOST_ADDR_DESC); | 747 | VHOST_ADDR_USED); |
748 | 748 | ||
749 | if (uaddr) | 749 | if (uaddr) |
750 | return __copy_to_user(uaddr, from, size); | 750 | return __copy_to_user(uaddr, from, size); |
@@ -959,21 +959,21 @@ static void vhost_iotlb_notify_vq(struct vhost_dev *d, | |||
959 | spin_unlock(&d->iotlb_lock); | 959 | spin_unlock(&d->iotlb_lock); |
960 | } | 960 | } |
961 | 961 | ||
962 | static int umem_access_ok(u64 uaddr, u64 size, int access) | 962 | static bool umem_access_ok(u64 uaddr, u64 size, int access) |
963 | { | 963 | { |
964 | unsigned long a = uaddr; | 964 | unsigned long a = uaddr; |
965 | 965 | ||
966 | /* Make sure 64 bit math will not overflow. */ | 966 | /* Make sure 64 bit math will not overflow. */ |
967 | if (vhost_overflow(uaddr, size)) | 967 | if (vhost_overflow(uaddr, size)) |
968 | return -EFAULT; | 968 | return false; |
969 | 969 | ||
970 | if ((access & VHOST_ACCESS_RO) && | 970 | if ((access & VHOST_ACCESS_RO) && |
971 | !access_ok(VERIFY_READ, (void __user *)a, size)) | 971 | !access_ok(VERIFY_READ, (void __user *)a, size)) |
972 | return -EFAULT; | 972 | return false; |
973 | if ((access & VHOST_ACCESS_WO) && | 973 | if ((access & VHOST_ACCESS_WO) && |
974 | !access_ok(VERIFY_WRITE, (void __user *)a, size)) | 974 | !access_ok(VERIFY_WRITE, (void __user *)a, size)) |
975 | return -EFAULT; | 975 | return false; |
976 | return 0; | 976 | return true; |
977 | } | 977 | } |
978 | 978 | ||
979 | static int vhost_process_iotlb_msg(struct vhost_dev *dev, | 979 | static int vhost_process_iotlb_msg(struct vhost_dev *dev, |
@@ -988,7 +988,7 @@ static int vhost_process_iotlb_msg(struct vhost_dev *dev, | |||
988 | ret = -EFAULT; | 988 | ret = -EFAULT; |
989 | break; | 989 | break; |
990 | } | 990 | } |
991 | if (umem_access_ok(msg->uaddr, msg->size, msg->perm)) { | 991 | if (!umem_access_ok(msg->uaddr, msg->size, msg->perm)) { |
992 | ret = -EFAULT; | 992 | ret = -EFAULT; |
993 | break; | 993 | break; |
994 | } | 994 | } |
@@ -1135,10 +1135,10 @@ static int vhost_iotlb_miss(struct vhost_virtqueue *vq, u64 iova, int access) | |||
1135 | return 0; | 1135 | return 0; |
1136 | } | 1136 | } |
1137 | 1137 | ||
1138 | static int vq_access_ok(struct vhost_virtqueue *vq, unsigned int num, | 1138 | static bool vq_access_ok(struct vhost_virtqueue *vq, unsigned int num, |
1139 | struct vring_desc __user *desc, | 1139 | struct vring_desc __user *desc, |
1140 | struct vring_avail __user *avail, | 1140 | struct vring_avail __user *avail, |
1141 | struct vring_used __user *used) | 1141 | struct vring_used __user *used) |
1142 | 1142 | ||
1143 | { | 1143 | { |
1144 | size_t s = vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; | 1144 | size_t s = vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; |
@@ -1161,8 +1161,8 @@ static void vhost_vq_meta_update(struct vhost_virtqueue *vq, | |||
1161 | vq->meta_iotlb[type] = node; | 1161 | vq->meta_iotlb[type] = node; |
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | static int iotlb_access_ok(struct vhost_virtqueue *vq, | 1164 | static bool iotlb_access_ok(struct vhost_virtqueue *vq, |
1165 | int access, u64 addr, u64 len, int type) | 1165 | int access, u64 addr, u64 len, int type) |
1166 | { | 1166 | { |
1167 | const struct vhost_umem_node *node; | 1167 | const struct vhost_umem_node *node; |
1168 | struct vhost_umem *umem = vq->iotlb; | 1168 | struct vhost_umem *umem = vq->iotlb; |
@@ -1220,7 +1220,7 @@ EXPORT_SYMBOL_GPL(vq_iotlb_prefetch); | |||
1220 | 1220 | ||
1221 | /* Can we log writes? */ | 1221 | /* Can we log writes? */ |
1222 | /* Caller should have device mutex but not vq mutex */ | 1222 | /* Caller should have device mutex but not vq mutex */ |
1223 | int vhost_log_access_ok(struct vhost_dev *dev) | 1223 | bool vhost_log_access_ok(struct vhost_dev *dev) |
1224 | { | 1224 | { |
1225 | return memory_access_ok(dev, dev->umem, 1); | 1225 | return memory_access_ok(dev, dev->umem, 1); |
1226 | } | 1226 | } |
@@ -1228,8 +1228,8 @@ EXPORT_SYMBOL_GPL(vhost_log_access_ok); | |||
1228 | 1228 | ||
1229 | /* Verify access for write logging. */ | 1229 | /* Verify access for write logging. */ |
1230 | /* Caller should have vq mutex and device mutex */ | 1230 | /* Caller should have vq mutex and device mutex */ |
1231 | static int vq_log_access_ok(struct vhost_virtqueue *vq, | 1231 | static bool vq_log_access_ok(struct vhost_virtqueue *vq, |
1232 | void __user *log_base) | 1232 | void __user *log_base) |
1233 | { | 1233 | { |
1234 | size_t s = vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; | 1234 | size_t s = vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; |
1235 | 1235 | ||
@@ -1242,12 +1242,14 @@ static int vq_log_access_ok(struct vhost_virtqueue *vq, | |||
1242 | 1242 | ||
1243 | /* Can we start vq? */ | 1243 | /* Can we start vq? */ |
1244 | /* Caller should have vq mutex and device mutex */ | 1244 | /* Caller should have vq mutex and device mutex */ |
1245 | int vhost_vq_access_ok(struct vhost_virtqueue *vq) | 1245 | bool vhost_vq_access_ok(struct vhost_virtqueue *vq) |
1246 | { | 1246 | { |
1247 | int ret = vq_log_access_ok(vq, vq->log_base); | 1247 | if (!vq_log_access_ok(vq, vq->log_base)) |
1248 | return false; | ||
1248 | 1249 | ||
1249 | if (ret || vq->iotlb) | 1250 | /* Access validation occurs at prefetch time with IOTLB */ |
1250 | return ret; | 1251 | if (vq->iotlb) |
1252 | return true; | ||
1251 | 1253 | ||
1252 | return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used); | 1254 | return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used); |
1253 | } | 1255 | } |
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index d8ee85ae8fdc..6c844b90a168 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h | |||
@@ -178,8 +178,8 @@ void vhost_dev_cleanup(struct vhost_dev *); | |||
178 | void vhost_dev_stop(struct vhost_dev *); | 178 | void vhost_dev_stop(struct vhost_dev *); |
179 | long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, void __user *argp); | 179 | long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, void __user *argp); |
180 | long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp); | 180 | long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp); |
181 | int vhost_vq_access_ok(struct vhost_virtqueue *vq); | 181 | bool vhost_vq_access_ok(struct vhost_virtqueue *vq); |
182 | int vhost_log_access_ok(struct vhost_dev *); | 182 | bool vhost_log_access_ok(struct vhost_dev *); |
183 | 183 | ||
184 | int vhost_get_vq_desc(struct vhost_virtqueue *, | 184 | int vhost_get_vq_desc(struct vhost_virtqueue *, |
185 | struct iovec iov[], unsigned int iov_count, | 185 | struct iovec iov[], unsigned int iov_count, |
diff --git a/include/net/slhc_vj.h b/include/net/slhc_vj.h index 8716d5942b65..8fcf8908a694 100644 --- a/include/net/slhc_vj.h +++ b/include/net/slhc_vj.h | |||
@@ -127,6 +127,7 @@ typedef __u32 int32; | |||
127 | */ | 127 | */ |
128 | struct cstate { | 128 | struct cstate { |
129 | byte_t cs_this; /* connection id number (xmit) */ | 129 | byte_t cs_this; /* connection id number (xmit) */ |
130 | bool initialized; /* true if initialized */ | ||
130 | struct cstate *next; /* next in ring (xmit) */ | 131 | struct cstate *next; /* next in ring (xmit) */ |
131 | struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ | 132 | struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ |
132 | struct tcphdr cs_tcp; | 133 | struct tcphdr cs_tcp; |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index a8772a978224..9c169bb2444d 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -781,8 +781,14 @@ static void ipgre_link_update(struct net_device *dev, bool set_mtu) | |||
781 | tunnel->encap.type == TUNNEL_ENCAP_NONE) { | 781 | tunnel->encap.type == TUNNEL_ENCAP_NONE) { |
782 | dev->features |= NETIF_F_GSO_SOFTWARE; | 782 | dev->features |= NETIF_F_GSO_SOFTWARE; |
783 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | 783 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; |
784 | } else { | ||
785 | dev->features &= ~NETIF_F_GSO_SOFTWARE; | ||
786 | dev->hw_features &= ~NETIF_F_GSO_SOFTWARE; | ||
784 | } | 787 | } |
785 | dev->features |= NETIF_F_LLTX; | 788 | dev->features |= NETIF_F_LLTX; |
789 | } else { | ||
790 | dev->hw_features &= ~NETIF_F_GSO_SOFTWARE; | ||
791 | dev->features &= ~(NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE); | ||
786 | } | 792 | } |
787 | } | 793 | } |
788 | 794 | ||
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 14b67dfacc4b..0fbd3ee26165 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -335,26 +335,6 @@ err_tlock: | |||
335 | } | 335 | } |
336 | EXPORT_SYMBOL_GPL(l2tp_session_register); | 336 | EXPORT_SYMBOL_GPL(l2tp_session_register); |
337 | 337 | ||
338 | /* Lookup a tunnel by id | ||
339 | */ | ||
340 | struct l2tp_tunnel *l2tp_tunnel_find(const struct net *net, u32 tunnel_id) | ||
341 | { | ||
342 | struct l2tp_tunnel *tunnel; | ||
343 | struct l2tp_net *pn = l2tp_pernet(net); | ||
344 | |||
345 | rcu_read_lock_bh(); | ||
346 | list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { | ||
347 | if (tunnel->tunnel_id == tunnel_id) { | ||
348 | rcu_read_unlock_bh(); | ||
349 | return tunnel; | ||
350 | } | ||
351 | } | ||
352 | rcu_read_unlock_bh(); | ||
353 | |||
354 | return NULL; | ||
355 | } | ||
356 | EXPORT_SYMBOL_GPL(l2tp_tunnel_find); | ||
357 | |||
358 | struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth) | 338 | struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth) |
359 | { | 339 | { |
360 | struct l2tp_net *pn = l2tp_pernet(net); | 340 | struct l2tp_net *pn = l2tp_pernet(net); |
@@ -1436,74 +1416,11 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 | |||
1436 | { | 1416 | { |
1437 | struct l2tp_tunnel *tunnel = NULL; | 1417 | struct l2tp_tunnel *tunnel = NULL; |
1438 | int err; | 1418 | int err; |
1439 | struct socket *sock = NULL; | ||
1440 | struct sock *sk = NULL; | ||
1441 | struct l2tp_net *pn; | ||
1442 | enum l2tp_encap_type encap = L2TP_ENCAPTYPE_UDP; | 1419 | enum l2tp_encap_type encap = L2TP_ENCAPTYPE_UDP; |
1443 | 1420 | ||
1444 | /* Get the tunnel socket from the fd, which was opened by | ||
1445 | * the userspace L2TP daemon. If not specified, create a | ||
1446 | * kernel socket. | ||
1447 | */ | ||
1448 | if (fd < 0) { | ||
1449 | err = l2tp_tunnel_sock_create(net, tunnel_id, peer_tunnel_id, | ||
1450 | cfg, &sock); | ||
1451 | if (err < 0) | ||
1452 | goto err; | ||
1453 | } else { | ||
1454 | sock = sockfd_lookup(fd, &err); | ||
1455 | if (!sock) { | ||
1456 | pr_err("tunl %u: sockfd_lookup(fd=%d) returned %d\n", | ||
1457 | tunnel_id, fd, err); | ||
1458 | err = -EBADF; | ||
1459 | goto err; | ||
1460 | } | ||
1461 | |||
1462 | /* Reject namespace mismatches */ | ||
1463 | if (!net_eq(sock_net(sock->sk), net)) { | ||
1464 | pr_err("tunl %u: netns mismatch\n", tunnel_id); | ||
1465 | err = -EINVAL; | ||
1466 | goto err; | ||
1467 | } | ||
1468 | } | ||
1469 | |||
1470 | sk = sock->sk; | ||
1471 | |||
1472 | if (cfg != NULL) | 1421 | if (cfg != NULL) |
1473 | encap = cfg->encap; | 1422 | encap = cfg->encap; |
1474 | 1423 | ||
1475 | /* Quick sanity checks */ | ||
1476 | err = -EPROTONOSUPPORT; | ||
1477 | if (sk->sk_type != SOCK_DGRAM) { | ||
1478 | pr_debug("tunl %hu: fd %d wrong socket type\n", | ||
1479 | tunnel_id, fd); | ||
1480 | goto err; | ||
1481 | } | ||
1482 | switch (encap) { | ||
1483 | case L2TP_ENCAPTYPE_UDP: | ||
1484 | if (sk->sk_protocol != IPPROTO_UDP) { | ||
1485 | pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n", | ||
1486 | tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP); | ||
1487 | goto err; | ||
1488 | } | ||
1489 | break; | ||
1490 | case L2TP_ENCAPTYPE_IP: | ||
1491 | if (sk->sk_protocol != IPPROTO_L2TP) { | ||
1492 | pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n", | ||
1493 | tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP); | ||
1494 | goto err; | ||
1495 | } | ||
1496 | break; | ||
1497 | } | ||
1498 | |||
1499 | /* Check if this socket has already been prepped */ | ||
1500 | tunnel = l2tp_tunnel(sk); | ||
1501 | if (tunnel != NULL) { | ||
1502 | /* This socket has already been prepped */ | ||
1503 | err = -EBUSY; | ||
1504 | goto err; | ||
1505 | } | ||
1506 | |||
1507 | tunnel = kzalloc(sizeof(struct l2tp_tunnel), GFP_KERNEL); | 1424 | tunnel = kzalloc(sizeof(struct l2tp_tunnel), GFP_KERNEL); |
1508 | if (tunnel == NULL) { | 1425 | if (tunnel == NULL) { |
1509 | err = -ENOMEM; | 1426 | err = -ENOMEM; |
@@ -1520,72 +1437,126 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 | |||
1520 | rwlock_init(&tunnel->hlist_lock); | 1437 | rwlock_init(&tunnel->hlist_lock); |
1521 | tunnel->acpt_newsess = true; | 1438 | tunnel->acpt_newsess = true; |
1522 | 1439 | ||
1523 | /* The net we belong to */ | ||
1524 | tunnel->l2tp_net = net; | ||
1525 | pn = l2tp_pernet(net); | ||
1526 | |||
1527 | if (cfg != NULL) | 1440 | if (cfg != NULL) |
1528 | tunnel->debug = cfg->debug; | 1441 | tunnel->debug = cfg->debug; |
1529 | 1442 | ||
1530 | /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */ | ||
1531 | tunnel->encap = encap; | 1443 | tunnel->encap = encap; |
1532 | if (encap == L2TP_ENCAPTYPE_UDP) { | ||
1533 | struct udp_tunnel_sock_cfg udp_cfg = { }; | ||
1534 | |||
1535 | udp_cfg.sk_user_data = tunnel; | ||
1536 | udp_cfg.encap_type = UDP_ENCAP_L2TPINUDP; | ||
1537 | udp_cfg.encap_rcv = l2tp_udp_encap_recv; | ||
1538 | udp_cfg.encap_destroy = l2tp_udp_encap_destroy; | ||
1539 | |||
1540 | setup_udp_tunnel_sock(net, sock, &udp_cfg); | ||
1541 | } else { | ||
1542 | sk->sk_user_data = tunnel; | ||
1543 | } | ||
1544 | 1444 | ||
1545 | /* Bump the reference count. The tunnel context is deleted | ||
1546 | * only when this drops to zero. A reference is also held on | ||
1547 | * the tunnel socket to ensure that it is not released while | ||
1548 | * the tunnel is extant. Must be done before sk_destruct is | ||
1549 | * set. | ||
1550 | */ | ||
1551 | refcount_set(&tunnel->ref_count, 1); | 1445 | refcount_set(&tunnel->ref_count, 1); |
1552 | sock_hold(sk); | ||
1553 | tunnel->sock = sk; | ||
1554 | tunnel->fd = fd; | 1446 | tunnel->fd = fd; |
1555 | 1447 | ||
1556 | /* Hook on the tunnel socket destructor so that we can cleanup | ||
1557 | * if the tunnel socket goes away. | ||
1558 | */ | ||
1559 | tunnel->old_sk_destruct = sk->sk_destruct; | ||
1560 | sk->sk_destruct = &l2tp_tunnel_destruct; | ||
1561 | lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock"); | ||
1562 | |||
1563 | sk->sk_allocation = GFP_ATOMIC; | ||
1564 | |||
1565 | /* Init delete workqueue struct */ | 1448 | /* Init delete workqueue struct */ |
1566 | INIT_WORK(&tunnel->del_work, l2tp_tunnel_del_work); | 1449 | INIT_WORK(&tunnel->del_work, l2tp_tunnel_del_work); |
1567 | 1450 | ||
1568 | /* Add tunnel to our list */ | ||
1569 | INIT_LIST_HEAD(&tunnel->list); | 1451 | INIT_LIST_HEAD(&tunnel->list); |
1570 | spin_lock_bh(&pn->l2tp_tunnel_list_lock); | ||
1571 | list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list); | ||
1572 | spin_unlock_bh(&pn->l2tp_tunnel_list_lock); | ||
1573 | 1452 | ||
1574 | err = 0; | 1453 | err = 0; |
1575 | err: | 1454 | err: |
1576 | if (tunnelp) | 1455 | if (tunnelp) |
1577 | *tunnelp = tunnel; | 1456 | *tunnelp = tunnel; |
1578 | 1457 | ||
1579 | /* If tunnel's socket was created by the kernel, it doesn't | ||
1580 | * have a file. | ||
1581 | */ | ||
1582 | if (sock && sock->file) | ||
1583 | sockfd_put(sock); | ||
1584 | |||
1585 | return err; | 1458 | return err; |
1586 | } | 1459 | } |
1587 | EXPORT_SYMBOL_GPL(l2tp_tunnel_create); | 1460 | EXPORT_SYMBOL_GPL(l2tp_tunnel_create); |
1588 | 1461 | ||
1462 | static int l2tp_validate_socket(const struct sock *sk, const struct net *net, | ||
1463 | enum l2tp_encap_type encap) | ||
1464 | { | ||
1465 | if (!net_eq(sock_net(sk), net)) | ||
1466 | return -EINVAL; | ||
1467 | |||
1468 | if (sk->sk_type != SOCK_DGRAM) | ||
1469 | return -EPROTONOSUPPORT; | ||
1470 | |||
1471 | if ((encap == L2TP_ENCAPTYPE_UDP && sk->sk_protocol != IPPROTO_UDP) || | ||
1472 | (encap == L2TP_ENCAPTYPE_IP && sk->sk_protocol != IPPROTO_L2TP)) | ||
1473 | return -EPROTONOSUPPORT; | ||
1474 | |||
1475 | if (sk->sk_user_data) | ||
1476 | return -EBUSY; | ||
1477 | |||
1478 | return 0; | ||
1479 | } | ||
1480 | |||
1481 | int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, | ||
1482 | struct l2tp_tunnel_cfg *cfg) | ||
1483 | { | ||
1484 | struct l2tp_tunnel *tunnel_walk; | ||
1485 | struct l2tp_net *pn; | ||
1486 | struct socket *sock; | ||
1487 | struct sock *sk; | ||
1488 | int ret; | ||
1489 | |||
1490 | if (tunnel->fd < 0) { | ||
1491 | ret = l2tp_tunnel_sock_create(net, tunnel->tunnel_id, | ||
1492 | tunnel->peer_tunnel_id, cfg, | ||
1493 | &sock); | ||
1494 | if (ret < 0) | ||
1495 | goto err; | ||
1496 | } else { | ||
1497 | sock = sockfd_lookup(tunnel->fd, &ret); | ||
1498 | if (!sock) | ||
1499 | goto err; | ||
1500 | |||
1501 | ret = l2tp_validate_socket(sock->sk, net, tunnel->encap); | ||
1502 | if (ret < 0) | ||
1503 | goto err_sock; | ||
1504 | } | ||
1505 | |||
1506 | sk = sock->sk; | ||
1507 | |||
1508 | sock_hold(sk); | ||
1509 | tunnel->sock = sk; | ||
1510 | tunnel->l2tp_net = net; | ||
1511 | |||
1512 | pn = l2tp_pernet(net); | ||
1513 | |||
1514 | spin_lock_bh(&pn->l2tp_tunnel_list_lock); | ||
1515 | list_for_each_entry(tunnel_walk, &pn->l2tp_tunnel_list, list) { | ||
1516 | if (tunnel_walk->tunnel_id == tunnel->tunnel_id) { | ||
1517 | spin_unlock_bh(&pn->l2tp_tunnel_list_lock); | ||
1518 | |||
1519 | ret = -EEXIST; | ||
1520 | goto err_sock; | ||
1521 | } | ||
1522 | } | ||
1523 | list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list); | ||
1524 | spin_unlock_bh(&pn->l2tp_tunnel_list_lock); | ||
1525 | |||
1526 | if (tunnel->encap == L2TP_ENCAPTYPE_UDP) { | ||
1527 | struct udp_tunnel_sock_cfg udp_cfg = { | ||
1528 | .sk_user_data = tunnel, | ||
1529 | .encap_type = UDP_ENCAP_L2TPINUDP, | ||
1530 | .encap_rcv = l2tp_udp_encap_recv, | ||
1531 | .encap_destroy = l2tp_udp_encap_destroy, | ||
1532 | }; | ||
1533 | |||
1534 | setup_udp_tunnel_sock(net, sock, &udp_cfg); | ||
1535 | } else { | ||
1536 | sk->sk_user_data = tunnel; | ||
1537 | } | ||
1538 | |||
1539 | tunnel->old_sk_destruct = sk->sk_destruct; | ||
1540 | sk->sk_destruct = &l2tp_tunnel_destruct; | ||
1541 | lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, | ||
1542 | "l2tp_sock"); | ||
1543 | sk->sk_allocation = GFP_ATOMIC; | ||
1544 | |||
1545 | if (tunnel->fd >= 0) | ||
1546 | sockfd_put(sock); | ||
1547 | |||
1548 | return 0; | ||
1549 | |||
1550 | err_sock: | ||
1551 | if (tunnel->fd < 0) | ||
1552 | sock_release(sock); | ||
1553 | else | ||
1554 | sockfd_put(sock); | ||
1555 | err: | ||
1556 | return ret; | ||
1557 | } | ||
1558 | EXPORT_SYMBOL_GPL(l2tp_tunnel_register); | ||
1559 | |||
1589 | /* This function is used by the netlink TUNNEL_DELETE command. | 1560 | /* This function is used by the netlink TUNNEL_DELETE command. |
1590 | */ | 1561 | */ |
1591 | void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) | 1562 | void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) |
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 2718d0b284d0..ba33cbec71eb 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h | |||
@@ -220,12 +220,14 @@ struct l2tp_session *l2tp_session_get(const struct net *net, | |||
220 | struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth); | 220 | struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth); |
221 | struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, | 221 | struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, |
222 | const char *ifname); | 222 | const char *ifname); |
223 | struct l2tp_tunnel *l2tp_tunnel_find(const struct net *net, u32 tunnel_id); | ||
224 | struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth); | 223 | struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth); |
225 | 224 | ||
226 | int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, | 225 | int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, |
227 | u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, | 226 | u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, |
228 | struct l2tp_tunnel **tunnelp); | 227 | struct l2tp_tunnel **tunnelp); |
228 | int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, | ||
229 | struct l2tp_tunnel_cfg *cfg); | ||
230 | |||
229 | void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel); | 231 | void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel); |
230 | void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel); | 232 | void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel); |
231 | struct l2tp_session *l2tp_session_create(int priv_size, | 233 | struct l2tp_session *l2tp_session_create(int priv_size, |
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index e7ea9c4b89ff..b05dbd9ffcb2 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c | |||
@@ -236,12 +236,6 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info | |||
236 | if (info->attrs[L2TP_ATTR_DEBUG]) | 236 | if (info->attrs[L2TP_ATTR_DEBUG]) |
237 | cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]); | 237 | cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]); |
238 | 238 | ||
239 | tunnel = l2tp_tunnel_find(net, tunnel_id); | ||
240 | if (tunnel != NULL) { | ||
241 | ret = -EEXIST; | ||
242 | goto out; | ||
243 | } | ||
244 | |||
245 | ret = -EINVAL; | 239 | ret = -EINVAL; |
246 | switch (cfg.encap) { | 240 | switch (cfg.encap) { |
247 | case L2TP_ENCAPTYPE_UDP: | 241 | case L2TP_ENCAPTYPE_UDP: |
@@ -251,9 +245,19 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info | |||
251 | break; | 245 | break; |
252 | } | 246 | } |
253 | 247 | ||
254 | if (ret >= 0) | 248 | if (ret < 0) |
255 | ret = l2tp_tunnel_notify(&l2tp_nl_family, info, | 249 | goto out; |
256 | tunnel, L2TP_CMD_TUNNEL_CREATE); | 250 | |
251 | l2tp_tunnel_inc_refcount(tunnel); | ||
252 | ret = l2tp_tunnel_register(tunnel, net, &cfg); | ||
253 | if (ret < 0) { | ||
254 | kfree(tunnel); | ||
255 | goto out; | ||
256 | } | ||
257 | ret = l2tp_tunnel_notify(&l2tp_nl_family, info, tunnel, | ||
258 | L2TP_CMD_TUNNEL_CREATE); | ||
259 | l2tp_tunnel_dec_refcount(tunnel); | ||
260 | |||
257 | out: | 261 | out: |
258 | return ret; | 262 | return ret; |
259 | } | 263 | } |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index d6deca11da19..896bbca9bdaa 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -698,6 +698,15 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
698 | error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, &tcfg, &tunnel); | 698 | error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, &tcfg, &tunnel); |
699 | if (error < 0) | 699 | if (error < 0) |
700 | goto end; | 700 | goto end; |
701 | |||
702 | l2tp_tunnel_inc_refcount(tunnel); | ||
703 | error = l2tp_tunnel_register(tunnel, sock_net(sk), | ||
704 | &tcfg); | ||
705 | if (error < 0) { | ||
706 | kfree(tunnel); | ||
707 | goto end; | ||
708 | } | ||
709 | drop_tunnel = true; | ||
701 | } | 710 | } |
702 | } else { | 711 | } else { |
703 | /* Error if we can't find the tunnel */ | 712 | /* Error if we can't find the tunnel */ |
diff --git a/net/rds/send.c b/net/rds/send.c index acad04243b41..94c7f74909be 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 Oracle. All rights reserved. | 2 | * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved. |
3 | * | 3 | * |
4 | * This software is available to you under a choice of one of two | 4 | * This software is available to you under a choice of one of two |
5 | * licenses. You may choose to be licensed under the terms of the GNU | 5 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -1017,10 +1017,15 @@ static int rds_send_mprds_hash(struct rds_sock *rs, struct rds_connection *conn) | |||
1017 | if (conn->c_npaths == 0 && hash != 0) { | 1017 | if (conn->c_npaths == 0 && hash != 0) { |
1018 | rds_send_ping(conn, 0); | 1018 | rds_send_ping(conn, 0); |
1019 | 1019 | ||
1020 | if (conn->c_npaths == 0) { | 1020 | /* The underlying connection is not up yet. Need to wait |
1021 | wait_event_interruptible(conn->c_hs_waitq, | 1021 | * until it is up to be sure that the non-zero c_path can be |
1022 | (conn->c_npaths != 0)); | 1022 | * used. But if we are interrupted, we have to use the zero |
1023 | } | 1023 | * c_path in case the connection ends up being non-MP capable. |
1024 | */ | ||
1025 | if (conn->c_npaths == 0) | ||
1026 | if (wait_event_interruptible(conn->c_hs_waitq, | ||
1027 | conn->c_npaths != 0)) | ||
1028 | hash = 0; | ||
1024 | if (conn->c_npaths == 1) | 1029 | if (conn->c_npaths == 1) |
1025 | hash = 0; | 1030 | hash = 0; |
1026 | } | 1031 | } |