-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAl7Eyq8ACgkQONu9yGCS aT5mkhAAzX7Y4/a4vbTw7qqO7Jg+XnipZQ2exrYPgjgtxxsh8cgtBFwOUMrdfkl7 EEx2OTT8feCQKOQoiyc0jkrQ9XtuoIH5D5mHPUV27kefPo9dIExej3MJKz7yFxOo mi017KYlMa27v9F13aBdzDYZDoaBvq5v4CZ+Ow6wl1ESh2/E1QZGMbNQvrRXo5ZB J3/HkyFsjzwhlwrcOCDMNM1qNEuC5U2xlrRL1cJZQ4bRZOVFITafZsOytzHW6i4x 9x1thYPiiH8mfBH/xqBn/m8U5SDE8w6aXGRtmesuh45HURkZ3XztARFIxoJwlvoZ nYyassflVRuQHr/RAIvSD+mWk0mWuYKgEjglWLZYfZJXYDSSn4v2C3SodVCBsaTr qaRpsJWTaZLzKHHe3lx9q6PhSFPQFpr1qoEsrFGAqj7HK+hahXqIGLoFlVA0Ytnt GWAgh/jc37gjbyGbUOPHdus+ghSrB/prUz+BCGhQDyfLhEpPMyE12/E/WQmKX3Ja omx1MCnXu4Fm7+cVOXV64Qz3vlwt8amqFpgldFCDB+dsvmWwWshhTqZh2rnxz6KI 1Arc53HdEJW1JawXTv/gW3VNj6BBnHwOzuhw1soEOKDd34bR88C6uJiLC1fRM3yG +vLI1U5ivdgQKst0Pd5xZQ7I2sNR63ryFLuTgtz6hYXk3ICs4CA= =ocXM -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEJDfLduVEy2qz2d/TmXOSYMtstxYFAl7E0iUACgkQmXOSYMts txYzNhAAipp0sKPe/Sx0vOYHmVPlvt9rutz5HxwPt1sNyM6uxodGYnarvUwkNV8V ZIkn92o9gLhSSISmzii6JN26Mu/bX3lJk40/me2X5erepknGnqAKBZ6e3SIV+HHr +chOLW5qDoSUKgWSlrr3qHa4yN/Ti3hNc7ATsWfESdVCAfna4p92O8gUhhkTa6pW akjVh+ZCO+7T4wV71Wqsm71DGJ1lYdh0jB5LrIIrBbwc+yY9pIOWCP+NbKuM+CIS vn4bi5tD9QhXp+JEnz802Qr1RmbaWoyuiTeBVn60h/6X3X4C8FYO62HXezjK6iEP NjSw06Uav40jCJpU567dAUv7CU+QoJOSGKoFmhw3yS180VE7iZreKJCoGGJHCi/E 3wmYENGQLYvvdL+421Z3ChwmhRuM7/DQyGOLeHHhXPLOlNqsUd45NbH9rOMAmTPR RxD9Lt7MoxqH6Pega4durCZR8pAQnh8amRb95fwxmWtR5ND1Cw5gc7pEWoPOt58J Kc0yoOjOJiD7RbimrZ29lT6c337/g1RCHNk1eyaPgAUsmGzIVZtCy725bHnL2299 ptt1GaiwFcJYB1l4MmpWeUW/j2wrvpSGNCfpb/vggEAg2AaDt82RyGT5TRF+sAVe RXJlSL+sFKaSEt/mRzwPAuLltTAc91WnNy5SXzKTzecUSKaxaiY= =bmRU -----END PGP SIGNATURE----- Merge 4.4.224 into kernel.lnx.4.4.r39-rel Changes in 4.4.224: (87 commits) USB: serial: qcserial: Add DW5816e support Revert "net: phy: Avoid polling PHY with PHY_IGNORE_INTERRUPTS" dp83640: reverse arguments to list_add_tail net/mlx4_core: Fix use of ENOSPC around mlx4_counter_alloc() sch_sfq: validate silly quantum values sch_choke: avoid potential panic in choke_reset() Revert "ACPI / video: Add force_native quirk for HP Pavilion dv6" enic: do not overwrite error code ipv6: fix cleanup ordering for ip6_mr failure binfmt_elf: move brk out of mmap when doing direct loader exec x86/apm: Don't access __preempt_count with zeroed fs Revert "IB/ipoib: Update broadcast object if PKey value was changed in index 0" USB: uas: add quirk for LaCie 2Big Quadra USB: serial: garmin_gps: add sanity checking for data length batman-adv: fix batadv_nc_random_weight_tq scripts/decodecode: fix trapping instruction formatting phy: micrel: Ensure interrupts are reenabled on resume binfmt_elf: Do not move brk for INTERP-less ET_EXEC ext4: add cond_resched() to ext4_protect_reserved_inode net: ipv6: add net argument to ip6_dst_lookup_flow net: ipv6_stub: use ip6_dst_lookup_flow instead of ip6_dst_lookup blktrace: Fix potential deadlock between delete & sysfs ops blktrace: fix unlocked access to init/start-stop/teardown blktrace: fix trace mutex deadlock blktrace: Protect q->blk_trace with RCU blktrace: fix dereference after null check ptp: do not explicitly set drvdata in ptp_clock_register() ptp: use is_visible method to hide unused attributes ptp: create "pins" together with the rest of attributes chardev: add helper function to register char devs with a struct device ptp: Fix pass zero to ERR_PTR() in ptp_clock_register ptp: fix the race between the release of ptp_clock and cdev ptp: free ptp device pin descriptors properly net: handle no dst on skb in icmp6_send net/sonic: Fix a resource leak in an error handling path in 'jazz_sonic_probe()' net: moxa: Fix a potential double 'free_irq()' drop_monitor: work around gcc-10 stringop-overflow warning scsi: sg: add sg_remove_request in sg_write spi: spi-dw: Add lock protect dw_spi rx/tx to prevent concurrent calls cifs: Check for timeout on Negotiate stage cifs: Fix a race condition with cifs_echo_request dmaengine: pch_dma.c: Avoid data race between probe and irq handler dmaengine: mmp_tdma: Reset channel error on release drm/qxl: lost qxl_bo_kunmap_atomic_page in qxl_image_init_helper() ipc/util.c: sysvipc_find_ipc() incorrectly updates position index net: openvswitch: fix csum updates for MPLS actions gre: do not keep the GRE header around in collect medata mode mm/memory_hotplug.c: fix overflow in test_pages_in_a_zone() scsi: qla2xxx: Avoid double completion of abort command i40e: avoid NVM acquire deadlock during NVM update net/mlx5: Fix driver load error flow when firmware is stuck netfilter: conntrack: avoid gcc-10 zero-length-bounds warning IB/mlx4: Test return value of calls to ib_get_cached_pkey pnp: Use list_for_each_entry() instead of open coding gcc-10 warnings: fix low-hanging fruit kbuild: compute false-positive -Wmaybe-uninitialized cases in Kconfig Stop the ad-hoc games with -Wno-maybe-initialized gcc-10: disable 'zero-length-bounds' warning for now gcc-10: disable 'array-bounds' warning for now gcc-10: disable 'stringop-overflow' warning for now gcc-10: disable 'restrict' warning for now block: defer timeouts to a workqueue blk-mq: Allow timeouts to run while queue is freezing blk-mq: sync the update nr_hw_queues with blk_mq_queue_tag_busy_iter blk-mq: Allow blocking queue tag iter callbacks x86/paravirt: Remove the unused irq_enable_sysexit pv op gcc-10: avoid shadowing standard library 'free()' in crypto net: fix a potential recursive NETDEV_FEAT_CHANGE net: ipv4: really enforce backoff for redirects netlabel: cope with NULL catmap ALSA: hda/realtek - Limit int mic boost for Thinkpad T530 ALSA: rawmidi: Fix racy buffer resize under concurrent accesses ALSA: rawmidi: Initialize allocated buffers USB: gadget: fix illegal array access in binding with UDC ARM: dts: imx27-phytec-phycard-s-rdk: Fix the I2C1 pinctrl entries x86: Fix early boot crash on gcc-10, third try exec: Move would_dump into flush_old_exec usb: gadget: net2272: Fix a memory leak in an error handling path in 'net2272_plat_probe()' usb: gadget: audio: Fix a missing error return value in audio_bind() usb: gadget: legacy: fix error return code in gncm_bind() usb: gadget: legacy: fix error return code in cdc_bind() Revert "ALSA: hda/realtek: Fix pop noise on ALC225" ARM: dts: r8a7740: Add missing extal2 to CPG node KVM: x86: Fix off-by-one error in kvm_vcpu_ioctl_x86_setup_mce Makefile: disallow data races on gcc-10 as well scsi: iscsi: Fix a potential deadlock in the timeout handler Linux 4.4.224 Signed-off-by: Nathan Chancellor <natechancellor@gmail.com> Conflicts: kernel/trace/blktrace.c sound/core/rawmidi.c
195 lines
5.4 KiB
C
195 lines
5.4 KiB
C
/*
|
|
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
|
* operating system. INET is implemented using the BSD Socket
|
|
* interface as the means of communication with the user level.
|
|
*
|
|
* Support for INET6 connection oriented protocols.
|
|
*
|
|
* Authors: See the TCPv6 sources
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or(at your option) any later version.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/in6.h>
|
|
#include <linux/ipv6.h>
|
|
#include <linux/jhash.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include <net/addrconf.h>
|
|
#include <net/inet_connection_sock.h>
|
|
#include <net/inet_ecn.h>
|
|
#include <net/inet_hashtables.h>
|
|
#include <net/ip6_route.h>
|
|
#include <net/sock.h>
|
|
#include <net/inet6_connection_sock.h>
|
|
|
|
int inet6_csk_bind_conflict(const struct sock *sk,
|
|
const struct inet_bind_bucket *tb, bool relax)
|
|
{
|
|
const struct sock *sk2;
|
|
int reuse = sk->sk_reuse;
|
|
int reuseport = sk->sk_reuseport;
|
|
kuid_t uid = sock_i_uid((struct sock *)sk);
|
|
|
|
/* We must walk the whole port owner list in this case. -DaveM */
|
|
/*
|
|
* See comment in inet_csk_bind_conflict about sock lookup
|
|
* vs net namespaces issues.
|
|
*/
|
|
sk_for_each_bound(sk2, &tb->owners) {
|
|
if (sk != sk2 &&
|
|
(!sk->sk_bound_dev_if ||
|
|
!sk2->sk_bound_dev_if ||
|
|
sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
|
|
if ((!reuse || !sk2->sk_reuse ||
|
|
sk2->sk_state == TCP_LISTEN) &&
|
|
(!reuseport || !sk2->sk_reuseport ||
|
|
(sk2->sk_state != TCP_TIME_WAIT &&
|
|
!uid_eq(uid,
|
|
sock_i_uid((struct sock *)sk2))))) {
|
|
if (ipv6_rcv_saddr_equal(sk, sk2))
|
|
break;
|
|
}
|
|
if (!relax && reuse && sk2->sk_reuse &&
|
|
sk2->sk_state != TCP_LISTEN &&
|
|
ipv6_rcv_saddr_equal(sk, sk2))
|
|
break;
|
|
}
|
|
}
|
|
|
|
return sk2 != NULL;
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict);
|
|
|
|
struct dst_entry *inet6_csk_route_req(const struct sock *sk,
|
|
struct flowi6 *fl6,
|
|
const struct request_sock *req,
|
|
u8 proto)
|
|
{
|
|
struct inet_request_sock *ireq = inet_rsk(req);
|
|
const struct ipv6_pinfo *np = inet6_sk(sk);
|
|
struct in6_addr *final_p, final;
|
|
struct dst_entry *dst;
|
|
|
|
memset(fl6, 0, sizeof(*fl6));
|
|
fl6->flowi6_proto = proto;
|
|
fl6->daddr = ireq->ir_v6_rmt_addr;
|
|
rcu_read_lock();
|
|
final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
|
|
rcu_read_unlock();
|
|
fl6->saddr = ireq->ir_v6_loc_addr;
|
|
fl6->flowi6_oif = ireq->ir_iif;
|
|
fl6->flowi6_mark = ireq->ir_mark;
|
|
fl6->fl6_dport = ireq->ir_rmt_port;
|
|
fl6->fl6_sport = htons(ireq->ir_num);
|
|
fl6->flowi6_uid = sk->sk_uid;
|
|
security_req_classify_flow(req, flowi6_to_flowi(fl6));
|
|
|
|
dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p);
|
|
if (IS_ERR(dst))
|
|
return NULL;
|
|
|
|
return dst;
|
|
}
|
|
EXPORT_SYMBOL(inet6_csk_route_req);
|
|
|
|
void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
|
|
{
|
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
|
|
|
|
sin6->sin6_family = AF_INET6;
|
|
sin6->sin6_addr = sk->sk_v6_daddr;
|
|
sin6->sin6_port = inet_sk(sk)->inet_dport;
|
|
/* We do not store received flowlabel for TCP */
|
|
sin6->sin6_flowinfo = 0;
|
|
sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
|
|
sk->sk_bound_dev_if);
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
|
|
|
|
static inline
|
|
struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
|
|
{
|
|
return __sk_dst_check(sk, cookie);
|
|
}
|
|
|
|
static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
|
|
struct flowi6 *fl6)
|
|
{
|
|
struct inet_sock *inet = inet_sk(sk);
|
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
|
struct in6_addr *final_p, final;
|
|
struct dst_entry *dst;
|
|
|
|
memset(fl6, 0, sizeof(*fl6));
|
|
fl6->flowi6_proto = sk->sk_protocol;
|
|
fl6->daddr = sk->sk_v6_daddr;
|
|
fl6->saddr = np->saddr;
|
|
fl6->flowlabel = np->flow_label;
|
|
IP6_ECN_flow_xmit(sk, fl6->flowlabel);
|
|
fl6->flowi6_oif = sk->sk_bound_dev_if;
|
|
fl6->flowi6_mark = sk->sk_mark;
|
|
fl6->fl6_sport = inet->inet_sport;
|
|
fl6->fl6_dport = inet->inet_dport;
|
|
fl6->flowi6_uid = sk->sk_uid;
|
|
security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
|
|
|
|
rcu_read_lock();
|
|
final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
|
|
rcu_read_unlock();
|
|
|
|
dst = __inet6_csk_dst_check(sk, np->dst_cookie);
|
|
if (!dst) {
|
|
dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p);
|
|
|
|
if (!IS_ERR(dst))
|
|
ip6_dst_store(sk, dst, NULL, NULL);
|
|
}
|
|
return dst;
|
|
}
|
|
|
|
int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused)
|
|
{
|
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
|
struct flowi6 fl6;
|
|
struct dst_entry *dst;
|
|
int res;
|
|
|
|
dst = inet6_csk_route_socket(sk, &fl6);
|
|
if (IS_ERR(dst)) {
|
|
sk->sk_err_soft = -PTR_ERR(dst);
|
|
sk->sk_route_caps = 0;
|
|
kfree_skb(skb);
|
|
return PTR_ERR(dst);
|
|
}
|
|
|
|
rcu_read_lock();
|
|
skb_dst_set_noref(skb, dst);
|
|
|
|
/* Restore final destination back after routing done */
|
|
fl6.daddr = sk->sk_v6_daddr;
|
|
|
|
res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
|
|
np->tclass);
|
|
rcu_read_unlock();
|
|
return res;
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet6_csk_xmit);
|
|
|
|
struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu)
|
|
{
|
|
struct flowi6 fl6;
|
|
struct dst_entry *dst = inet6_csk_route_socket(sk, &fl6);
|
|
|
|
if (IS_ERR(dst))
|
|
return NULL;
|
|
dst->ops->update_pmtu(dst, sk, NULL, mtu);
|
|
|
|
dst = inet6_csk_route_socket(sk, &fl6);
|
|
return IS_ERR(dst) ? NULL : dst;
|
|
}
|
|
EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu);
|