mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAl1iS9UACgkQONu9yGCS aT69qBAAxcqiiC4Mww7maN3wrJztZQiShKr2d/6B+koVBhG289fUQRcqrU4aDtaB Odf8NZPi19WaZM3dAdP2ReTCbUM7sVPHFTiwBhnba1dKyIeZmjOMxaCtxdGRVHs3 DLDcUT874nx4EHrQoRQErJeZeyQQ3KytXmfqJKFyhplX0fDt6w2E/g1ZZpcngpNH S8KAmfy2WWcauguPJ8RGugSvn+3YC6TMerz96vNNiiPr3np0oVIsbVmo81/sKApK dPKZ2qn4l7fYNIKfDxFnnbxBNoPvd35i0CsHxhB3dX/EYGp3ARHDWclMC8e1G+bp M8dicq/Ew7AfQoVQcLZD13eBTEk8iyAAeAmMoP9OlxkrOx2V2dNyMZG6bjAgosXx /39MP68tQMchSmCjK95KbPX1EN5jHeG97weP3Fqtf8NIG8K0gLUgHJidG+8J2H94 grPZD/w78HgYOqVVsF5v4qX9B8QcSuH4PzQ7mhoksJiW+X/TlIAI6GwbUsoXw6cu mYLgTr9hd/ZAGF6VQGNHAZ2UZfg377bN8hCXRWZay/t9JOZiqMJAOSjNAs+hL2LT fbHqmKnHF92mB0v+jEn7mJXuAhHQ3wCU314ZO/zk9sxLFp/caUbV+b+1oXlTGwq7 JMeRjrxrAKVfHgPgkhcWc9bTq9MhjZ4j7GypsBMxLbIqnlU8gzE= =9QYX -----END PGP SIGNATURE----- Merge 4.14.140 into android-4.14 Changes in 4.14.140 scsi: mpt3sas: Use 63-bit DMA addressing on SAS35 HBA sh: kernel: hw_breakpoint: Fix missing break in switch statement mm/usercopy: use memory range to be accessed for wraparound check mm/memcontrol.c: fix use after free in mem_cgroup_iter() bpf: get rid of pure_initcall dependency to enable jits bpf: restrict access to core bpf sysctls bpf: add bpf_jit_limit knob to restrict unpriv allocations x86/mm: Use WRITE_ONCE() when setting PTEs xtensa: add missing isync to the cpu_reset TLB code ALSA: hda - Apply workaround for another AMD chip 1022:1487 ALSA: hda - Fix a memory leak bug ALSA: hda - Add a generic reboot_notify ALSA: hda - Let all conexant codec enter D3 when rebooting HID: holtek: test for sanity of intfdata HID: hiddev: avoid opening a disconnected device HID: hiddev: do cleanup in failure of opening a device Input: kbtab - sanity check for endpoint type Input: iforce - add sanity checks net: usb: pegasus: fix improper read if get_registers() fail netfilter: ebtables: also count base chain policies clk: at91: generated: Truncate divisor to GENERATED_MAX_DIV + 1 clk: renesas: cpg-mssr: Fix reset control race condition xen/pciback: remove set but not used variable 'old_state' irqchip/gic-v3-its: Free unused vpt_page when alloc vpe table fail irqchip/irq-imx-gpcv2: Forward irq type to parent perf header: Fix divide by zero error if f_header.attr_size==0 perf header: Fix use of unitialized value warning libata: zpodd: Fix small read overflow in zpodd_get_mech_type() drm/bridge: lvds-encoder: Fix build error while CONFIG_DRM_KMS_HELPER=m scsi: hpsa: correct scsi command status issue after reset scsi: qla2xxx: Fix possible fcport null-pointer dereferences ata: libahci: do not complain in case of deferred probe kbuild: modpost: handle KBUILD_EXTRA_SYMBOLS only for external modules arm64/efi: fix variable 'si' set but not used arm64: unwind: Prohibit probing on return_address() arm64/mm: fix variable 'pud' set but not used IB/core: Add mitigation for Spectre V1 IB/mad: Fix use-after-free in ib mad completion handling drm: msm: Fix add_gpu_components ocfs2: remove set but not used variable 'last_hash' asm-generic: fix -Wtype-limits compiler warnings KVM: arm/arm64: Sync ICH_VMCR_EL2 back when about to block staging: comedi: dt3000: Fix signed integer overflow 'divider * base' staging: comedi: dt3000: Fix rounding up of timer divisor iio: adc: max9611: Fix temperature reading in probe USB: core: Fix races in character device registration and deregistraion usb: gadget: udc: renesas_usb3: Fix sysfs interface of "role" usb: cdc-acm: make sure a refcount is taken early enough USB: CDC: fix sanity checks in CDC union parser USB: serial: option: add D-Link DWM-222 device ID USB: serial: option: Add support for ZTE MF871A USB: serial: option: add the BroadMobi BM818 card USB: serial: option: Add Motorola modem UARTs bpf: fix bpf_jit_limit knob for PAGE_SIZE >= 64K Revert "tcp: Clear sk_send_head after purging the write queue" arm64: compat: Allow single-byte watchpoints on all addresses arm64: ftrace: Ensure module ftrace trampoline is coherent with I-side netfilter: conntrack: Use consistent ct id hash calculation Input: psmouse - fix build error of multiple definition iommu/amd: Move iommu_init_pci() to .init section bnx2x: Fix VF's VLAN reconfiguration in reload. net/mlx4_en: fix a memory leak bug net/packet: fix race in tpacket_snd() sctp: fix the transport error_count check xen/netback: Reset nr_frags before freeing skb net/mlx5e: Only support tx/rx pause setting for port owner net/mlx5e: Use flow keys dissector to parse packets for ARFS team: Add vlan tx offload to hw_enc_features bonding: Add vlan tx offload to hw_enc_features mmc: sdhci-of-arasan: Do now show error message in case of deffered probe xfrm: policy: remove pcpu policy cache Linux 4.14.140 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
204 lines
4.4 KiB
C
204 lines
4.4 KiB
C
/*
|
|
* xfrm_device.c - IPsec device offloading code.
|
|
*
|
|
* Copyright (c) 2015 secunet Security Networks AG
|
|
*
|
|
* Author:
|
|
* Steffen Klassert <steffen.klassert@secunet.com>
|
|
*
|
|
* 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/errno.h>
|
|
#include <linux/module.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/skbuff.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/spinlock.h>
|
|
#include <net/dst.h>
|
|
#include <net/xfrm.h>
|
|
#include <linux/notifier.h>
|
|
|
|
#ifdef CONFIG_XFRM_OFFLOAD
|
|
int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features)
|
|
{
|
|
int err;
|
|
struct xfrm_state *x;
|
|
struct xfrm_offload *xo = xfrm_offload(skb);
|
|
|
|
if (skb_is_gso(skb))
|
|
return 0;
|
|
|
|
if (xo) {
|
|
x = skb->sp->xvec[skb->sp->len - 1];
|
|
if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND)
|
|
return 0;
|
|
|
|
x->outer_mode->xmit(x, skb);
|
|
|
|
err = x->type_offload->xmit(x, skb, features);
|
|
if (err) {
|
|
XFRM_INC_STATS(xs_net(x), LINUX_MIB_XFRMOUTSTATEPROTOERROR);
|
|
return err;
|
|
}
|
|
|
|
skb_push(skb, skb->data - skb_mac_header(skb));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
|
|
|
|
int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
|
|
struct xfrm_user_offload *xuo)
|
|
{
|
|
int err;
|
|
struct dst_entry *dst;
|
|
struct net_device *dev;
|
|
struct xfrm_state_offload *xso = &x->xso;
|
|
xfrm_address_t *saddr;
|
|
xfrm_address_t *daddr;
|
|
|
|
if (!x->type_offload)
|
|
return -EINVAL;
|
|
|
|
/* We don't yet support UDP encapsulation, TFC padding and ESN. */
|
|
if (x->encap || x->tfcpad || (x->props.flags & XFRM_STATE_ESN))
|
|
return 0;
|
|
|
|
dev = dev_get_by_index(net, xuo->ifindex);
|
|
if (!dev) {
|
|
if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) {
|
|
saddr = &x->props.saddr;
|
|
daddr = &x->id.daddr;
|
|
} else {
|
|
saddr = &x->id.daddr;
|
|
daddr = &x->props.saddr;
|
|
}
|
|
|
|
dst = __xfrm_dst_lookup(net, 0, 0, saddr, daddr,
|
|
x->props.family,
|
|
xfrm_smark_get(0, x));
|
|
if (IS_ERR(dst))
|
|
return 0;
|
|
|
|
dev = dst->dev;
|
|
|
|
dev_hold(dev);
|
|
dst_release(dst);
|
|
}
|
|
|
|
if (!dev->xfrmdev_ops || !dev->xfrmdev_ops->xdo_dev_state_add) {
|
|
xso->dev = NULL;
|
|
dev_put(dev);
|
|
return 0;
|
|
}
|
|
|
|
xso->dev = dev;
|
|
xso->num_exthdrs = 1;
|
|
xso->flags = xuo->flags;
|
|
|
|
err = dev->xfrmdev_ops->xdo_dev_state_add(x);
|
|
if (err) {
|
|
dev_put(dev);
|
|
return err;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(xfrm_dev_state_add);
|
|
|
|
bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
|
|
{
|
|
int mtu;
|
|
struct dst_entry *dst = skb_dst(skb);
|
|
struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
|
|
struct net_device *dev = x->xso.dev;
|
|
|
|
if (!x->type_offload || x->encap)
|
|
return false;
|
|
|
|
if ((x->xso.offload_handle && (dev == dst->path->dev)) &&
|
|
!dst->child->xfrm && x->type->get_mtu) {
|
|
mtu = x->type->get_mtu(x, xdst->child_mtu_cached);
|
|
|
|
if (skb->len <= mtu)
|
|
goto ok;
|
|
|
|
if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu))
|
|
goto ok;
|
|
}
|
|
|
|
return false;
|
|
|
|
ok:
|
|
if (dev && dev->xfrmdev_ops && dev->xfrmdev_ops->xdo_dev_offload_ok)
|
|
return x->xso.dev->xfrmdev_ops->xdo_dev_offload_ok(skb, x);
|
|
|
|
return true;
|
|
}
|
|
EXPORT_SYMBOL_GPL(xfrm_dev_offload_ok);
|
|
#endif
|
|
|
|
static int xfrm_dev_register(struct net_device *dev)
|
|
{
|
|
if ((dev->features & NETIF_F_HW_ESP) && !dev->xfrmdev_ops)
|
|
return NOTIFY_BAD;
|
|
if ((dev->features & NETIF_F_HW_ESP_TX_CSUM) &&
|
|
!(dev->features & NETIF_F_HW_ESP))
|
|
return NOTIFY_BAD;
|
|
|
|
return NOTIFY_DONE;
|
|
}
|
|
|
|
static int xfrm_dev_feat_change(struct net_device *dev)
|
|
{
|
|
if ((dev->features & NETIF_F_HW_ESP) && !dev->xfrmdev_ops)
|
|
return NOTIFY_BAD;
|
|
else if (!(dev->features & NETIF_F_HW_ESP))
|
|
dev->xfrmdev_ops = NULL;
|
|
|
|
if ((dev->features & NETIF_F_HW_ESP_TX_CSUM) &&
|
|
!(dev->features & NETIF_F_HW_ESP))
|
|
return NOTIFY_BAD;
|
|
|
|
return NOTIFY_DONE;
|
|
}
|
|
|
|
static int xfrm_dev_down(struct net_device *dev)
|
|
{
|
|
if (dev->features & NETIF_F_HW_ESP)
|
|
xfrm_dev_state_flush(dev_net(dev), dev, true);
|
|
|
|
return NOTIFY_DONE;
|
|
}
|
|
|
|
static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
|
|
{
|
|
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
|
|
|
switch (event) {
|
|
case NETDEV_REGISTER:
|
|
return xfrm_dev_register(dev);
|
|
|
|
case NETDEV_FEAT_CHANGE:
|
|
return xfrm_dev_feat_change(dev);
|
|
|
|
case NETDEV_DOWN:
|
|
return xfrm_dev_down(dev);
|
|
}
|
|
return NOTIFY_DONE;
|
|
}
|
|
|
|
static struct notifier_block xfrm_dev_notifier = {
|
|
.notifier_call = xfrm_dev_event,
|
|
};
|
|
|
|
void __net_init xfrm_dev_init(void)
|
|
{
|
|
register_netdevice_notifier(&xfrm_dev_notifier);
|
|
}
|