Merge android11-5.4.86+ (5d7dfa3) into msm-5.4

* refs/heads/tmp-5d7dfa3:
  ANDROID: ABI: update allowed list for galaxy
  ANDROID: Add vendor hooks when syscall prctl finished
  ANDROID: cgroup: Add vendor hook to the cgroup
  ANDROID: db845c: Use FRAGMENT_CONFIG
  ANDROID: abi_gki_aarch64_db845c: Update symbols for boot regression
  ANDROID: sched: move vendor hook to check scheduling nice value
  ANDROID: GKI: bring back icmpv6_send
  UPSTREAM: net: icmp: pass zeroed opts from icmp{,v6}_ndo_send before sending
  UPSTREAM: ipv6: silence compilation warning for non-IPV6 builds
  UPSTREAM: ipv6: icmp6: avoid indirect call for icmpv6_send()
  UPSTREAM: xfrm: interface: use icmp_ndo_send helper
  UPSTREAM: sunvnet: use icmp_ndo_send helper
  UPSTREAM: gtp: use icmp_ndo_send helper
  UPSTREAM: icmp: allow icmpv6_ndo_send to work with CONFIG_IPV6=n
  UPSTREAM: icmp: introduce helper for nat'd source address in network device context
  ANDROID: ABI: Update allowed list for QCOM
  ANDROID: ABI: Update allowed list for QCOM
  ANDROID: Adding kprobes build configs for Cuttlefish

Change-Id: I12c72a46fa19c09e46884318597241f63d15bb4e
Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
This commit is contained in:
Srinivasarao P 2021-04-22 10:27:30 +05:30
commit 8e3b6c3a70
25 changed files with 4618 additions and 4431 deletions

File diff suppressed because it is too large Load Diff

View File

@ -750,12 +750,14 @@
match_token
noop_llseek
notify_change
override_creds
pagecache_get_page
path_get
path_put
__put_cred
__put_page
register_filesystem
revert_creds
set_anon_super
sget
simple_getattr

View File

@ -3,6 +3,7 @@
__alloc_disk_node
__alloc_pages_nodemask
__alloc_percpu
__alloc_percpu_gfp
__alloc_skb
__arch_clear_user
__arch_copy_from_user
@ -133,6 +134,7 @@
__request_module
__request_percpu_irq
__request_region
__sbitmap_queue_get
__scsi_device_lookup_by_target
__scsi_execute
__scsi_print_sense
@ -267,7 +269,13 @@
blk_execute_rq_nowait
blk_get_request
blk_lookup_devt
blk_mq_bio_list_merge
blk_mq_rq_cpu
blk_mq_run_hw_queue
blk_mq_sched_mark_restart_hctx
blk_mq_sched_request_inserted
blk_mq_sched_try_insert_merge
blk_mq_sched_try_merge
blk_put_request
blk_queue_bounce_limit
blk_queue_max_hw_sectors
@ -275,6 +283,7 @@
blk_rq_map_user
blk_rq_map_user_iov
blk_rq_unmap_user
blk_stat_enable_accounting
blk_verify_command
blkdev_get_by_dev
blkdev_get_by_path
@ -955,6 +964,17 @@
dw_pcie_read
dw_pcie_setup_rc
dw_pcie_write
elevator_alloc
elv_bio_merge_ok
elv_rb_add
elv_rb_del
elv_rb_find
elv_rb_former_request
elv_rb_latter_request
elv_register
elv_rqhash_add
elv_rqhash_del
elv_unregister
emergency_restart
enable_irq
enable_percpu_irq
@ -1233,6 +1253,7 @@
int_sqrt
int_to_scsilun
invalidate_mapping_pages
ioc_lookup_icq
iomem_resource
iommu_alloc_resv_region
iommu_attach_device
@ -1406,6 +1427,7 @@
kstrtoull
kstrtoull_from_user
kthread_bind
kthread_blkcg
kthread_cancel_delayed_work_sync
kthread_cancel_work_sync
kthread_create_on_node
@ -2011,6 +2033,14 @@
runqueues
save_stack_trace
save_stack_trace_tsk
sbitmap_add_wait_queue
sbitmap_any_bit_set
sbitmap_del_wait_queue
sbitmap_init_node
sbitmap_queue_clear
sbitmap_queue_init_node
sbitmap_queue_min_shallow_depth
sbitmap_queue_resize
sched_clock
sched_setscheduler
sched_setscheduler_nocheck
@ -2386,6 +2416,7 @@
thermal_zone_of_sensor_register
thermal_zone_of_sensor_unregister
time64_to_tm
timer_reduce
timespec64_to_jiffies
touch_softlockup_watchdog
trace_define_field

View File

@ -1058,13 +1058,20 @@
hwspin_lock_unregister
__hwspin_unlock
hypervisor_kobj
i2c_adapter_type
i2c_add_adapter
i2c_add_numbered_adapter
i2c_del_adapter
i2c_del_driver
i2c_get_device_id
i2c_get_dma_safe_msg_buf
i2c_put_dma_safe_msg_buf
i2c_register_driver
i2c_smbus_read_byte
i2c_smbus_write_byte
__i2c_smbus_xfer
i2c_smbus_xfer
__i2c_transfer
i2c_transfer
i2c_transfer_buffer_flags
icc_get
@ -1209,6 +1216,7 @@
irq_domain_remove
irq_domain_set_hwirq_and_chip
irq_domain_set_info
irq_domain_simple_ops
irq_domain_update_bus_token
irq_domain_xlate_onecell
irq_domain_xlate_twocell
@ -2013,6 +2021,9 @@
rtc_tm_to_time64
rtc_update_irq
rtc_valid_tm
rt_mutex_lock
rt_mutex_trylock
rt_mutex_unlock
rtnl_is_locked
rtnl_link_register
rtnl_link_unregister
@ -2862,3 +2873,7 @@
xdp_rxq_info_reg
xdp_rxq_info_reg_mem_model
xdp_rxq_info_unreg
pci_get_slot
pcie_capability_clear_and_set_word
pci_device_is_present
pci_find_bus

View File

@ -3,7 +3,8 @@
BUILD_INITRAMFS=1
DEFCONFIG=db845c_gki_defconfig
PRE_DEFCONFIG_CMDS="KCONFIG_CONFIG=${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/${DEFCONFIG} ${ROOT_DIR}/${KERNEL_DIR}/scripts/kconfig/merge_config.sh -m -r ${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/gki_defconfig ${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/db845c_gki.fragment"
FRAGMENT_CONFIG=${KERNEL_DIR}/arch/arm64/configs/db845c_gki.fragment
PRE_DEFCONFIG_CMDS="KCONFIG_CONFIG=${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/${DEFCONFIG} ${ROOT_DIR}/${KERNEL_DIR}/scripts/kconfig/merge_config.sh -m -r ${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/gki_defconfig ${ROOT_DIR}/${FRAGMENT_CONFIG}"
POST_DEFCONFIG_CMDS="rm ${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/${DEFCONFIG}"
FILES="

19
build.config.gki_kprobes Normal file
View File

@ -0,0 +1,19 @@
DEFCONFIG=gki_defconfig
POST_DEFCONFIG_CMDS="check_defconfig && update_kprobes_config"
function update_kprobes_config() {
${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
-d CONFIG_LTO \
-d CONFIG_LTO_CLANG \
-d CONFIG_CFI_CLANG \
-d CFI_PERMISSIVE \
-d CFI_CLANG \
-e CONFIG_FUNCTION_TRACER \
-e CONFIG_IRQSOFF_TRACER \
-e CONFIG_PREEMPT_TRACER \
-e CONFIG_DEBUG_FS \
-e CONFIG_CHECKPOINT_RESTORE \
-d CONFIG_RANDOMIZE_BASE
(cd ${OUT_DIR} && \
make ${CC_LD_ARG} O=${OUT_DIR} olddefconfig)
}

View File

@ -0,0 +1,4 @@
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.common
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.aarch64
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.gki_kprobes

View File

@ -0,0 +1,4 @@
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.common
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.x86_64
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.gki_kprobes

View File

@ -20,6 +20,8 @@
#include <trace/hooks/minidump.h>
#include <trace/hooks/wqlockup.h>
#include <trace/hooks/sysrqcrash.h>
#include <trace/hooks/cgroup.h>
#include <trace/hooks/sys.h>
/*
* Export tracepoints that act as a bare tracehook (ie: have no trace event
@ -69,3 +71,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sysrq_crash);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_find_busiest_group);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_map_util_freq);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_em_pd_energy);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cgroup_set_task);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_syscall_prctl_finished);

View File

@ -1353,27 +1353,12 @@ sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
if (vio_version_after_eq(&port->vio, 1, 3))
localmtu -= VLAN_HLEN;
if (skb->protocol == htons(ETH_P_IP)) {
struct flowi4 fl4;
struct rtable *rt = NULL;
memset(&fl4, 0, sizeof(fl4));
fl4.flowi4_oif = dev->ifindex;
fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
fl4.daddr = ip_hdr(skb)->daddr;
fl4.saddr = ip_hdr(skb)->saddr;
rt = ip_route_output_key(dev_net(dev), &fl4);
if (!IS_ERR(rt)) {
skb_dst_set(skb, &rt->dst);
icmp_send(skb, ICMP_DEST_UNREACH,
ICMP_FRAG_NEEDED,
htonl(localmtu));
}
}
if (skb->protocol == htons(ETH_P_IP))
icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
htonl(localmtu));
#if IS_ENABLED(CONFIG_IPV6)
else if (skb->protocol == htons(ETH_P_IPV6))
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu);
icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu);
#endif
goto out_dropped;
}

View File

@ -545,9 +545,8 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
if (!skb_is_gso(skb) && (iph->frag_off & htons(IP_DF)) &&
mtu < ntohs(iph->tot_len)) {
netdev_dbg(dev, "packet too big, fragmentation needed\n");
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
htonl(mtu));
icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
htonl(mtu));
goto err_rt;
}

View File

@ -3,6 +3,7 @@
#define _LINUX_ICMPV6_H
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <uapi/linux/icmpv6.h>
static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
@ -13,21 +14,61 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
#include <linux/netdevice.h>
#if IS_ENABLED(CONFIG_IPV6)
extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
const struct in6_addr *force_saddr);
const struct in6_addr *force_saddr,
const struct inet6_skb_parm *parm);
void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
const struct in6_addr *force_saddr,
const struct inet6_skb_parm *parm);
#if IS_BUILTIN(CONFIG_IPV6)
static inline void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
const struct inet6_skb_parm *parm)
{
icmp6_send(skb, type, code, info, NULL, parm);
}
static inline int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
{
BUILD_BUG_ON(fn != icmp6_send);
return 0;
}
static inline int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn)
{
BUILD_BUG_ON(fn != icmp6_send);
return 0;
}
#else
extern void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
const struct inet6_skb_parm *parm);
extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
#endif
void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
unsigned int data_len);
#if IS_ENABLED(CONFIG_NF_NAT)
void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info);
#else
static inline void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
{
struct inet6_skb_parm parm = { 0 };
__icmpv6_send(skb_in, type, code, info, &parm);
}
#endif
#else
static inline void icmpv6_send(struct sk_buff *skb,
u8 type, u8 code, __u32 info)
{
}
static inline void icmpv6_ndo_send(struct sk_buff *skb,
u8 type, u8 code, __u32 info)
{
}
#endif

View File

@ -90,7 +90,6 @@ struct ipv6_params {
__s32 autoconf;
};
extern struct ipv6_params ipv6_defaults;
#include <linux/icmpv6.h>
#include <linux/tcp.h>
#include <linux/udp.h>

View File

@ -43,6 +43,16 @@ static inline void icmp_send(struct sk_buff *skb_in, int type, int code, __be32
__icmp_send(skb_in, type, code, info, &IPCB(skb_in)->opt);
}
#if IS_ENABLED(CONFIG_NF_NAT)
void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info);
#else
static inline void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info)
{
struct ip_options opts = { 0 };
__icmp_send(skb_in, type, code, info, &opts);
}
#endif
int icmp_rcv(struct sk_buff *skb);
int icmp_err(struct sk_buff *skb, u32 info);
int icmp_init(void);

View File

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM cgroup
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH trace/hooks
#if !defined(_TRACE_HOOK_CGROUP_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_CGROUP_H
#include <linux/tracepoint.h>
#include <trace/hooks/vendor_hooks.h>
struct task_struct;
DECLARE_HOOK(android_vh_cgroup_set_task,
TP_PROTO(int ret, struct task_struct *task),
TP_ARGS(ret, task));
#endif
#include <trace/define_trace.h>

View File

@ -58,8 +58,8 @@ DECLARE_RESTRICTED_HOOK(android_rvh_rtmutex_prepare_setprio,
TP_ARGS(p, pi_task), 1);
DECLARE_RESTRICTED_HOOK(android_rvh_set_user_nice,
TP_PROTO(struct task_struct *p, long *nice),
TP_ARGS(p, nice), 1);
TP_PROTO(struct task_struct *p, long *nice, bool *allowed),
TP_ARGS(p, nice, allowed), 1);
DECLARE_RESTRICTED_HOOK(android_rvh_setscheduler,
TP_PROTO(struct task_struct *p),

17
include/trace/hooks/sys.h Normal file
View File

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM sys
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH trace/hooks
#if !defined(_TRACE_HOOK_SYS_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_SYS_H
#include <linux/tracepoint.h>
#include <trace/hooks/vendor_hooks.h>
struct task_struct;
DECLARE_HOOK(android_vh_syscall_prctl_finished,
TP_PROTO(int option, struct task_struct *task),
TP_ARGS(option, task));
#endif
#include <trace/define_trace.h>

View File

@ -17,6 +17,7 @@
#include <linux/fs_parser.h>
#include <trace/events/cgroup.h>
#include <trace/hooks/cgroup.h>
#define cg_invalf(fc, fmt, ...) invalf(fc, fmt, ## __VA_ARGS__)
@ -522,6 +523,7 @@ static ssize_t __cgroup1_procs_write(struct kernfs_open_file *of,
goto out_finish;
ret = cgroup_attach_task(cgrp, task, threadgroup);
trace_android_vh_cgroup_set_task(ret, task);
out_finish:
cgroup_procs_write_finish(task);

View File

@ -4773,12 +4773,13 @@ static inline int rt_effective_prio(struct task_struct *p, int prio)
void set_user_nice(struct task_struct *p, long nice)
{
bool queued, running;
bool queued, running, allowed = false;
int old_prio, delta;
struct rq_flags rf;
struct rq *rq;
if (task_nice(p) == nice || nice < MIN_NICE || nice > MAX_NICE)
trace_android_rvh_set_user_nice(p, &nice, &allowed);
if ((task_nice(p) == nice || nice < MIN_NICE || nice > MAX_NICE) && !allowed)
return;
/*
* We have to be careful, if called from sys_setpriority(),
@ -4786,7 +4787,6 @@ void set_user_nice(struct task_struct *p, long nice)
*/
rq = task_rq_lock(p, &rf);
update_rq_clock(rq);
trace_android_rvh_set_user_nice(p, &nice);
/*
* The RT priorities are set via sched_setscheduler(), but we still

View File

@ -75,6 +75,8 @@
#include "uid16.h"
#include <trace/hooks/sys.h>
#ifndef SET_UNALIGN_CTL
# define SET_UNALIGN_CTL(a, b) (-EINVAL)
#endif
@ -2644,6 +2646,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
error = -EINVAL;
break;
}
trace_android_vh_syscall_prctl_finished(option, me);
return error;
}

View File

@ -750,6 +750,40 @@ out:;
}
EXPORT_SYMBOL(__icmp_send);
#if IS_ENABLED(CONFIG_NF_NAT)
#include <net/netfilter/nf_conntrack.h>
void icmp_ndo_send(struct sk_buff *skb_in, int type, int code, __be32 info)
{
struct sk_buff *cloned_skb = NULL;
struct ip_options opts = { 0 };
enum ip_conntrack_info ctinfo;
struct nf_conn *ct;
__be32 orig_ip;
ct = nf_ct_get(skb_in, &ctinfo);
if (!ct || !(ct->status & IPS_SRC_NAT)) {
__icmp_send(skb_in, type, code, info, &opts);
return;
}
if (skb_shared(skb_in))
skb_in = cloned_skb = skb_clone(skb_in, GFP_ATOMIC);
if (unlikely(!skb_in || skb_network_header(skb_in) < skb_in->head ||
(skb_network_header(skb_in) + sizeof(struct iphdr)) >
skb_tail_pointer(skb_in) || skb_ensure_writable(skb_in,
skb_network_offset(skb_in) + sizeof(struct iphdr))))
goto out;
orig_ip = ip_hdr(skb_in)->saddr;
ip_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.ip;
__icmp_send(skb_in, type, code, info, &opts);
ip_hdr(skb_in)->saddr = orig_ip;
out:
consume_skb(cloned_skb);
}
EXPORT_SYMBOL(icmp_ndo_send);
#endif
static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
{

View File

@ -306,10 +306,9 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
}
#if IS_ENABLED(CONFIG_IPV6_MIP6)
static void mip6_addr_swap(struct sk_buff *skb)
static void mip6_addr_swap(struct sk_buff *skb, const struct inet6_skb_parm *opt)
{
struct ipv6hdr *iph = ipv6_hdr(skb);
struct inet6_skb_parm *opt = IP6CB(skb);
struct ipv6_destopt_hao *hao;
struct in6_addr tmp;
int off;
@ -326,7 +325,7 @@ static void mip6_addr_swap(struct sk_buff *skb)
}
}
#else
static inline void mip6_addr_swap(struct sk_buff *skb) {}
static inline void mip6_addr_swap(struct sk_buff *skb, const struct inet6_skb_parm *opt) {}
#endif
static struct dst_entry *icmpv6_route_lookup(struct net *net,
@ -420,8 +419,9 @@ static int icmp6_iif(const struct sk_buff *skb)
/*
* Send an ICMP message in response to a packet in error
*/
static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
const struct in6_addr *force_saddr)
void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
const struct in6_addr *force_saddr,
const struct inet6_skb_parm *parm)
{
struct inet6_dev *idev = NULL;
struct ipv6hdr *hdr = ipv6_hdr(skb);
@ -514,7 +514,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
if (!(skb->dev->flags & IFF_LOOPBACK) && !icmpv6_global_allow(net, type))
goto out_bh_enable;
mip6_addr_swap(skb);
mip6_addr_swap(skb, parm);
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_ICMPV6;
@ -594,12 +594,13 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
out_bh_enable:
local_bh_enable();
}
EXPORT_SYMBOL(icmp6_send);
/* Slightly more convenient version of icmp6_send.
*/
void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
{
icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL);
icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL, IP6CB(skb));
kfree_skb(skb);
}
@ -656,10 +657,10 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
}
if (type == ICMP_TIME_EXCEEDED)
icmp6_send(skb2, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
info, &temp_saddr);
info, &temp_saddr, IP6CB(skb2));
else
icmp6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH,
info, &temp_saddr);
info, &temp_saddr, IP6CB(skb2));
if (rt)
ip6_rt_put(rt);

View File

@ -9,6 +9,8 @@
#if IS_ENABLED(CONFIG_IPV6)
#if !IS_BUILTIN(CONFIG_IPV6)
static ip6_icmp_send_t __rcu *ip6_icmp_send;
int inet6_register_icmp_sender(ip6_icmp_send_t *fn)
@ -31,18 +33,64 @@ int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn)
}
EXPORT_SYMBOL(inet6_unregister_icmp_sender);
void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
void __icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
const struct inet6_skb_parm *parm)
{
ip6_icmp_send_t *send;
rcu_read_lock();
send = rcu_dereference(ip6_icmp_send);
if (!send)
goto out;
send(skb, type, code, info, NULL);
out:
if (send)
send(skb, type, code, info, NULL, parm);
rcu_read_unlock();
}
EXPORT_SYMBOL(icmpv6_send);
EXPORT_SYMBOL(__icmpv6_send);
#endif
/*
* ANDROID API HACK for android11-5.4 branch only
*
* Work around loss of icmpv6_send global symbol that got moved to __icmpv6_send
* in 5.4.102
*/
void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
{
__icmpv6_send(skb, type, code, info, IP6CB(skb));
}
EXPORT_SYMBOL(icmpv6_send);
#if IS_ENABLED(CONFIG_NF_NAT)
#include <net/netfilter/nf_conntrack.h>
void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info)
{
struct inet6_skb_parm parm = { 0 };
struct sk_buff *cloned_skb = NULL;
enum ip_conntrack_info ctinfo;
struct in6_addr orig_ip;
struct nf_conn *ct;
ct = nf_ct_get(skb_in, &ctinfo);
if (!ct || !(ct->status & IPS_SRC_NAT)) {
__icmpv6_send(skb_in, type, code, info, &parm);
return;
}
if (skb_shared(skb_in))
skb_in = cloned_skb = skb_clone(skb_in, GFP_ATOMIC);
if (unlikely(!skb_in || skb_network_header(skb_in) < skb_in->head ||
(skb_network_header(skb_in) + sizeof(struct ipv6hdr)) >
skb_tail_pointer(skb_in) || skb_ensure_writable(skb_in,
skb_network_offset(skb_in) + sizeof(struct ipv6hdr))))
goto out;
orig_ip = ipv6_hdr(skb_in)->saddr;
ipv6_hdr(skb_in)->saddr = ct->tuplehash[0].tuple.src.u3.in6;
__icmpv6_send(skb_in, type, code, info, &parm);
ipv6_hdr(skb_in)->saddr = orig_ip;
out:
consume_skb(cloned_skb);
}
EXPORT_SYMBOL(icmpv6_ndo_send);
#endif
#endif

View File

@ -300,10 +300,10 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
} else {
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
htonl(mtu));
icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
htonl(mtu));
}
dst_release(dst);