Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix IGMP handling wrt VRF, from David Ahern. 2) Fix timer access to freed object in dccp, from Eric Dumazet. 3) Use kmalloc_array() in ptr_ring to avoid overflow cases which are triggerable by userspace. Also from Eric Dumazet. 4) Fix infinite loop in unmapping cleanup of nfp driver, from Colin Ian King. 5) Correct datagram peek handling of empty SKBs, from Matthew Dawson. 6) Fix use after free in TIPC, from Eric Dumazet. 7) When replacing a route in ipv6 we need to reset the round robin pointer, from Wei Wang. 8) Fix bug in pci_find_pcie_root_port() which was unearthed by the relaxed ordering changes, from Thierry Redding. I made sure to get an explicit ACK from Bjorn this time around :-) * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (27 commits) ipv6: repair fib6 tree in failure case net_sched: fix order of queue length updates in qdisc_replace() tools lib bpf: improve warning switchdev: documentation: minor typo fixes bpf, doc: also add s390x as arch to sysctl description net: sched: fix NULL pointer dereference when action calls some targets rxrpc: Fix oops when discarding a preallocated service call irda: do not leak initialized list.dev to userspace net/mlx4_core: Enable 4K UAR if SRIOV module parameter is not enabled PCI: Allow PCI express root ports to find themselves tcp: when rearming RTO, if RTO time is in past then fire RTO ASAP net: check and errout if res->fi is NULL when RTM_F_FIB_MATCH is set ipv6: reset fn->rr_ptr when replacing route sctp: fully initialize the IPv6 address in sctp_v6_to_addr() tipc: fix use-after-free tun: handle register_netdevice() failures properly datagram: When peeking datagrams with offset < 0 don't skip empty skbs bpf, doc: improve sysctl knob description netxen: fix incorrect loop counter decrement nfp: fix infinite loop on umapping cleanup ...
This commit is contained in:
commit
e3181f2c0c
@ -228,7 +228,7 @@ Learning on the device port should be enabled, as well as learning_sync:
|
||||
bridge link set dev DEV learning on self
|
||||
bridge link set dev DEV learning_sync on self
|
||||
|
||||
Learning_sync attribute enables syncing of the learned/forgotton FDB entry to
|
||||
Learning_sync attribute enables syncing of the learned/forgotten FDB entry to
|
||||
the bridge's FDB. It's possible, but not optimal, to enable learning on the
|
||||
device port and on the bridge port, and disable learning_sync.
|
||||
|
||||
@ -245,7 +245,7 @@ the responsibility of the port driver/device to age out these entries. If the
|
||||
port device supports ageing, when the FDB entry expires, it will notify the
|
||||
driver which in turn will notify the bridge with SWITCHDEV_FDB_DEL. If the
|
||||
device does not support ageing, the driver can simulate ageing using a
|
||||
garbage collection timer to monitor FBD entries. Expired entries will be
|
||||
garbage collection timer to monitor FDB entries. Expired entries will be
|
||||
notified to the bridge using SWITCHDEV_FDB_DEL. See rocker driver for
|
||||
example of driver running ageing timer.
|
||||
|
||||
|
@ -35,9 +35,34 @@ Table : Subdirectories in /proc/sys/net
|
||||
bpf_jit_enable
|
||||
--------------
|
||||
|
||||
This enables Berkeley Packet Filter Just in Time compiler.
|
||||
Currently supported on x86_64 architecture, bpf_jit provides a framework
|
||||
to speed packet filtering, the one used by tcpdump/libpcap for example.
|
||||
This enables the BPF Just in Time (JIT) compiler. BPF is a flexible
|
||||
and efficient infrastructure allowing to execute bytecode at various
|
||||
hook points. It is used in a number of Linux kernel subsystems such
|
||||
as networking (e.g. XDP, tc), tracing (e.g. kprobes, uprobes, tracepoints)
|
||||
and security (e.g. seccomp). LLVM has a BPF back end that can compile
|
||||
restricted C into a sequence of BPF instructions. After program load
|
||||
through bpf(2) and passing a verifier in the kernel, a JIT will then
|
||||
translate these BPF proglets into native CPU instructions. There are
|
||||
two flavors of JITs, the newer eBPF JIT currently supported on:
|
||||
- x86_64
|
||||
- arm64
|
||||
- ppc64
|
||||
- sparc64
|
||||
- mips64
|
||||
- s390x
|
||||
|
||||
And the older cBPF JIT supported on the following archs:
|
||||
- arm
|
||||
- mips
|
||||
- ppc
|
||||
- sparc
|
||||
|
||||
eBPF JITs are a superset of cBPF JITs, meaning the kernel will
|
||||
migrate cBPF instructions into eBPF instructions and then JIT
|
||||
compile them transparently. Older cBPF JITs can only translate
|
||||
tcpdump filters, seccomp rules, etc, but not mentioned eBPF
|
||||
programs loaded through bpf(2).
|
||||
|
||||
Values :
|
||||
0 - disable the JIT (default value)
|
||||
1 - enable the JIT
|
||||
@ -46,9 +71,9 @@ Values :
|
||||
bpf_jit_harden
|
||||
--------------
|
||||
|
||||
This enables hardening for the Berkeley Packet Filter Just in Time compiler.
|
||||
Supported are eBPF JIT backends. Enabling hardening trades off performance,
|
||||
but can mitigate JIT spraying.
|
||||
This enables hardening for the BPF JIT compiler. Supported are eBPF
|
||||
JIT backends. Enabling hardening trades off performance, but can
|
||||
mitigate JIT spraying.
|
||||
Values :
|
||||
0 - disable JIT hardening (default value)
|
||||
1 - enable JIT hardening for unprivileged users only
|
||||
@ -57,11 +82,11 @@ Values :
|
||||
bpf_jit_kallsyms
|
||||
----------------
|
||||
|
||||
When Berkeley Packet Filter Just in Time compiler is enabled, then compiled
|
||||
images are unknown addresses to the kernel, meaning they neither show up in
|
||||
traces nor in /proc/kallsyms. This enables export of these addresses, which
|
||||
can be used for debugging/tracing. If bpf_jit_harden is enabled, this feature
|
||||
is disabled.
|
||||
When BPF JIT compiler is enabled, then compiled images are unknown
|
||||
addresses to the kernel, meaning they neither show up in traces nor
|
||||
in /proc/kallsyms. This enables export of these addresses, which can
|
||||
be used for debugging/tracing. If bpf_jit_harden is enabled, this
|
||||
feature is disabled.
|
||||
Values :
|
||||
0 - disable JIT kallsyms export (default value)
|
||||
1 - enable JIT kallsyms export for privileged users only
|
||||
|
@ -432,7 +432,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
||||
/* Virtual PCI function needs to determine UAR page size from
|
||||
* firmware. Only master PCI function can set the uar page size
|
||||
*/
|
||||
if (enable_4k_uar)
|
||||
if (enable_4k_uar || !dev->persist->num_vfs)
|
||||
dev->uar_page_shift = DEFAULT_UAR_PAGE_SHIFT;
|
||||
else
|
||||
dev->uar_page_shift = PAGE_SHIFT;
|
||||
@ -2277,7 +2277,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
|
||||
|
||||
dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1;
|
||||
|
||||
if (enable_4k_uar) {
|
||||
if (enable_4k_uar || !dev->persist->num_vfs) {
|
||||
init_hca.log_uar_sz = ilog2(dev->caps.num_uars) +
|
||||
PAGE_SHIFT - DEFAULT_UAR_PAGE_SHIFT;
|
||||
init_hca.uar_page_sz = DEFAULT_UAR_PAGE_SHIFT - 12;
|
||||
|
@ -908,8 +908,7 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
err_unmap:
|
||||
--f;
|
||||
while (f >= 0) {
|
||||
while (--f >= 0) {
|
||||
frag = &skb_shinfo(skb)->frags[f];
|
||||
dma_unmap_page(dp->dev, tx_ring->txbufs[wr_idx].dma_addr,
|
||||
skb_frag_size(frag), DMA_TO_DEVICE);
|
||||
|
@ -2311,7 +2311,7 @@ netxen_md_rdqueue(struct netxen_adapter *adapter,
|
||||
loop_cnt++) {
|
||||
NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, queue_id);
|
||||
read_addr = queueEntry->read_addr;
|
||||
for (k = 0; k < read_cnt; k--) {
|
||||
for (k = 0; k < read_cnt; k++) {
|
||||
NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0,
|
||||
&read_value);
|
||||
*data_buff++ = read_value;
|
||||
|
@ -1879,6 +1879,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
|
||||
|
||||
err_detach:
|
||||
tun_detach_all(dev);
|
||||
/* register_netdevice() already called tun_free_netdev() */
|
||||
goto err_free_dev;
|
||||
|
||||
err_free_flow:
|
||||
tun_flow_uninit(tun);
|
||||
security_tun_dev_free_security(tun->security);
|
||||
|
@ -514,7 +514,7 @@ EXPORT_SYMBOL(pci_find_resource);
|
||||
*/
|
||||
struct pci_dev *pci_find_pcie_root_port(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *bridge, *highest_pcie_bridge = NULL;
|
||||
struct pci_dev *bridge, *highest_pcie_bridge = dev;
|
||||
|
||||
bridge = pci_upstream_bridge(dev);
|
||||
while (bridge && pci_is_pcie(bridge)) {
|
||||
@ -522,11 +522,10 @@ struct pci_dev *pci_find_pcie_root_port(struct pci_dev *dev)
|
||||
bridge = pci_upstream_bridge(bridge);
|
||||
}
|
||||
|
||||
if (highest_pcie_bridge &&
|
||||
pci_pcie_type(highest_pcie_bridge) == PCI_EXP_TYPE_ROOT_PORT)
|
||||
return highest_pcie_bridge;
|
||||
if (pci_pcie_type(highest_pcie_bridge) != PCI_EXP_TYPE_ROOT_PORT)
|
||||
return NULL;
|
||||
|
||||
return NULL;
|
||||
return highest_pcie_bridge;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_find_pcie_root_port);
|
||||
|
||||
|
@ -436,9 +436,9 @@ static inline int ptr_ring_consume_batched_bh(struct ptr_ring *r,
|
||||
__PTR_RING_PEEK_CALL_v; \
|
||||
})
|
||||
|
||||
static inline void **__ptr_ring_init_queue_alloc(int size, gfp_t gfp)
|
||||
static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp)
|
||||
{
|
||||
return kzalloc(ALIGN(size * sizeof(void *), SMP_CACHE_BYTES), gfp);
|
||||
return kcalloc(size, sizeof(void *), gfp);
|
||||
}
|
||||
|
||||
static inline void __ptr_ring_set_size(struct ptr_ring *r, int size)
|
||||
@ -582,7 +582,8 @@ static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp,
|
||||
* In particular if you consume ring in interrupt or BH context, you must
|
||||
* disable interrupts/BH when doing so.
|
||||
*/
|
||||
static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings,
|
||||
static inline int ptr_ring_resize_multiple(struct ptr_ring **rings,
|
||||
unsigned int nrings,
|
||||
int size,
|
||||
gfp_t gfp, void (*destroy)(void *))
|
||||
{
|
||||
@ -590,7 +591,7 @@ static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings,
|
||||
void ***queues;
|
||||
int i;
|
||||
|
||||
queues = kmalloc(nrings * sizeof *queues, gfp);
|
||||
queues = kmalloc_array(nrings, sizeof(*queues), gfp);
|
||||
if (!queues)
|
||||
goto noqueues;
|
||||
|
||||
|
@ -193,7 +193,8 @@ static inline int skb_array_resize(struct skb_array *a, int size, gfp_t gfp)
|
||||
}
|
||||
|
||||
static inline int skb_array_resize_multiple(struct skb_array **rings,
|
||||
int nrings, int size, gfp_t gfp)
|
||||
int nrings, unsigned int size,
|
||||
gfp_t gfp)
|
||||
{
|
||||
BUILD_BUG_ON(offsetof(struct skb_array, ring));
|
||||
return ptr_ring_resize_multiple((struct ptr_ring **)rings,
|
||||
|
@ -352,7 +352,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
|
||||
!forwarding)
|
||||
return dst_mtu(dst);
|
||||
|
||||
return min(dst->dev->mtu, IP_MAX_MTU);
|
||||
return min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU);
|
||||
}
|
||||
|
||||
static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
|
||||
@ -364,7 +364,7 @@ static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
|
||||
return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding);
|
||||
}
|
||||
|
||||
return min(skb_dst(skb)->dev->mtu, IP_MAX_MTU);
|
||||
return min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU);
|
||||
}
|
||||
|
||||
u32 ip_idents_reserve(u32 hash, int segs);
|
||||
|
@ -806,8 +806,11 @@ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
|
||||
old = *pold;
|
||||
*pold = new;
|
||||
if (old != NULL) {
|
||||
qdisc_tree_reduce_backlog(old, old->q.qlen, old->qstats.backlog);
|
||||
unsigned int qlen = old->q.qlen;
|
||||
unsigned int backlog = old->qstats.backlog;
|
||||
|
||||
qdisc_reset(old);
|
||||
qdisc_tree_reduce_backlog(old, qlen, backlog);
|
||||
}
|
||||
sch_tree_unlock(sch);
|
||||
|
||||
|
@ -507,9 +507,7 @@ int sk_set_peek_off(struct sock *sk, int val);
|
||||
static inline int sk_peek_offset(struct sock *sk, int flags)
|
||||
{
|
||||
if (unlikely(flags & MSG_PEEK)) {
|
||||
s32 off = READ_ONCE(sk->sk_peek_off);
|
||||
if (off >= 0)
|
||||
return off;
|
||||
return READ_ONCE(sk->sk_peek_off);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -169,14 +169,20 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
|
||||
int *peeked, int *off, int *err,
|
||||
struct sk_buff **last)
|
||||
{
|
||||
bool peek_at_off = false;
|
||||
struct sk_buff *skb;
|
||||
int _off = *off;
|
||||
int _off = 0;
|
||||
|
||||
if (unlikely(flags & MSG_PEEK && *off >= 0)) {
|
||||
peek_at_off = true;
|
||||
_off = *off;
|
||||
}
|
||||
|
||||
*last = queue->prev;
|
||||
skb_queue_walk(queue, skb) {
|
||||
if (flags & MSG_PEEK) {
|
||||
if (_off >= skb->len && (skb->len || _off ||
|
||||
skb->peeked)) {
|
||||
if (peek_at_off && _off >= skb->len &&
|
||||
(_off || skb->peeked)) {
|
||||
_off -= skb->len;
|
||||
continue;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <net/checksum.h>
|
||||
|
||||
#include <net/inet_sock.h>
|
||||
#include <net/inet_common.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/xfrm.h>
|
||||
|
||||
@ -170,6 +171,15 @@ const char *dccp_packet_name(const int type)
|
||||
|
||||
EXPORT_SYMBOL_GPL(dccp_packet_name);
|
||||
|
||||
static void dccp_sk_destruct(struct sock *sk)
|
||||
{
|
||||
struct dccp_sock *dp = dccp_sk(sk);
|
||||
|
||||
ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
|
||||
dp->dccps_hc_tx_ccid = NULL;
|
||||
inet_sock_destruct(sk);
|
||||
}
|
||||
|
||||
int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
|
||||
{
|
||||
struct dccp_sock *dp = dccp_sk(sk);
|
||||
@ -179,6 +189,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
|
||||
icsk->icsk_syn_retries = sysctl_dccp_request_retries;
|
||||
sk->sk_state = DCCP_CLOSED;
|
||||
sk->sk_write_space = dccp_write_space;
|
||||
sk->sk_destruct = dccp_sk_destruct;
|
||||
icsk->icsk_sync_mss = dccp_sync_mss;
|
||||
dp->dccps_mss_cache = 536;
|
||||
dp->dccps_rate_last = jiffies;
|
||||
@ -219,8 +230,7 @@ void dccp_destroy_sock(struct sock *sk)
|
||||
dp->dccps_hc_rx_ackvec = NULL;
|
||||
}
|
||||
ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
|
||||
ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
|
||||
dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
|
||||
dp->dccps_hc_rx_ccid = NULL;
|
||||
|
||||
/* clean up feature negotiation state */
|
||||
dccp_feat_list_purge(&dp->dccps_featneg);
|
||||
|
@ -1007,10 +1007,18 @@ int igmp_rcv(struct sk_buff *skb)
|
||||
{
|
||||
/* This basically follows the spec line by line -- see RFC1112 */
|
||||
struct igmphdr *ih;
|
||||
struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
|
||||
struct net_device *dev = skb->dev;
|
||||
struct in_device *in_dev;
|
||||
int len = skb->len;
|
||||
bool dropped = true;
|
||||
|
||||
if (netif_is_l3_master(dev)) {
|
||||
dev = dev_get_by_index_rcu(dev_net(dev), IPCB(skb)->iif);
|
||||
if (!dev)
|
||||
goto drop;
|
||||
}
|
||||
|
||||
in_dev = __in_dev_get_rcu(dev);
|
||||
if (!in_dev)
|
||||
goto drop;
|
||||
|
||||
|
@ -1267,7 +1267,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
|
||||
if (mtu)
|
||||
return mtu;
|
||||
|
||||
mtu = dst->dev->mtu;
|
||||
mtu = READ_ONCE(dst->dev->mtu);
|
||||
|
||||
if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
|
||||
if (rt->rt_uses_gateway && mtu > 576)
|
||||
@ -2763,14 +2763,21 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
||||
if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
|
||||
table_id = rt->rt_table_id;
|
||||
|
||||
if (rtm->rtm_flags & RTM_F_FIB_MATCH)
|
||||
if (rtm->rtm_flags & RTM_F_FIB_MATCH) {
|
||||
if (!res.fi) {
|
||||
err = fib_props[res.type].error;
|
||||
if (!err)
|
||||
err = -EHOSTUNREACH;
|
||||
goto errout_free;
|
||||
}
|
||||
err = fib_dump_info(skb, NETLINK_CB(in_skb).portid,
|
||||
nlh->nlmsg_seq, RTM_NEWROUTE, table_id,
|
||||
rt->rt_type, res.prefix, res.prefixlen,
|
||||
fl4.flowi4_tos, res.fi, 0);
|
||||
else
|
||||
} else {
|
||||
err = rt_fill_info(net, dst, src, table_id, &fl4, skb,
|
||||
NETLINK_CB(in_skb).portid, nlh->nlmsg_seq);
|
||||
}
|
||||
if (err < 0)
|
||||
goto errout_free;
|
||||
|
||||
|
@ -3009,8 +3009,7 @@ void tcp_rearm_rto(struct sock *sk)
|
||||
/* delta_us may not be positive if the socket is locked
|
||||
* when the retrans timer fires and is rescheduled.
|
||||
*/
|
||||
if (delta_us > 0)
|
||||
rto = usecs_to_jiffies(delta_us);
|
||||
rto = usecs_to_jiffies(max_t(int, delta_us, 1));
|
||||
}
|
||||
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, rto,
|
||||
TCP_RTO_MAX);
|
||||
|
@ -1574,7 +1574,8 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
|
||||
return ip_recv_error(sk, msg, len, addr_len);
|
||||
|
||||
try_again:
|
||||
peeking = off = sk_peek_offset(sk, flags);
|
||||
peeking = flags & MSG_PEEK;
|
||||
off = sk_peek_offset(sk, flags);
|
||||
skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err);
|
||||
if (!skb)
|
||||
return err;
|
||||
|
@ -914,6 +914,8 @@ add:
|
||||
}
|
||||
nsiblings = iter->rt6i_nsiblings;
|
||||
fib6_purge_rt(iter, fn, info->nl_net);
|
||||
if (fn->rr_ptr == iter)
|
||||
fn->rr_ptr = NULL;
|
||||
rt6_release(iter);
|
||||
|
||||
if (nsiblings) {
|
||||
@ -926,6 +928,8 @@ add:
|
||||
if (rt6_qualify_for_ecmp(iter)) {
|
||||
*ins = iter->dst.rt6_next;
|
||||
fib6_purge_rt(iter, fn, info->nl_net);
|
||||
if (fn->rr_ptr == iter)
|
||||
fn->rr_ptr = NULL;
|
||||
rt6_release(iter);
|
||||
nsiblings--;
|
||||
} else {
|
||||
@ -1014,7 +1018,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
|
||||
/* Create subtree root node */
|
||||
sfn = node_alloc();
|
||||
if (!sfn)
|
||||
goto st_failure;
|
||||
goto failure;
|
||||
|
||||
sfn->leaf = info->nl_net->ipv6.ip6_null_entry;
|
||||
atomic_inc(&info->nl_net->ipv6.ip6_null_entry->rt6i_ref);
|
||||
@ -1031,12 +1035,12 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
|
||||
|
||||
if (IS_ERR(sn)) {
|
||||
/* If it is failed, discard just allocated
|
||||
root, and then (in st_failure) stale node
|
||||
root, and then (in failure) stale node
|
||||
in main tree.
|
||||
*/
|
||||
node_free(sfn);
|
||||
err = PTR_ERR(sn);
|
||||
goto st_failure;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Now link new subtree to main tree */
|
||||
@ -1051,7 +1055,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
|
||||
|
||||
if (IS_ERR(sn)) {
|
||||
err = PTR_ERR(sn);
|
||||
goto st_failure;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1092,18 +1096,17 @@ out:
|
||||
atomic_inc(&pn->leaf->rt6i_ref);
|
||||
}
|
||||
#endif
|
||||
/* Always release dst as dst->__refcnt is guaranteed
|
||||
* to be taken before entering this function
|
||||
*/
|
||||
dst_release_immediate(&rt->dst);
|
||||
goto failure;
|
||||
}
|
||||
return err;
|
||||
|
||||
#ifdef CONFIG_IPV6_SUBTREES
|
||||
/* Subtree creation failed, probably main tree node
|
||||
is orphan. If it is, shoot it.
|
||||
failure:
|
||||
/* fn->leaf could be NULL if fn is an intermediate node and we
|
||||
* failed to add the new route to it in both subtree creation
|
||||
* failure and fib6_add_rt2node() failure case.
|
||||
* In both cases, fib6_repair_tree() should be called to fix
|
||||
* fn->leaf.
|
||||
*/
|
||||
st_failure:
|
||||
if (fn && !(fn->fn_flags & (RTN_RTINFO|RTN_ROOT)))
|
||||
fib6_repair_tree(info->nl_net, fn);
|
||||
/* Always release dst as dst->__refcnt is guaranteed
|
||||
@ -1111,7 +1114,6 @@ st_failure:
|
||||
*/
|
||||
dst_release_immediate(&rt->dst);
|
||||
return err;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -362,7 +362,8 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
|
||||
return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
|
||||
|
||||
try_again:
|
||||
peeking = off = sk_peek_offset(sk, flags);
|
||||
peeking = flags & MSG_PEEK;
|
||||
off = sk_peek_offset(sk, flags);
|
||||
skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err);
|
||||
if (!skb)
|
||||
return err;
|
||||
|
@ -2213,7 +2213,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct irda_sock *self = irda_sk(sk);
|
||||
struct irda_device_list list;
|
||||
struct irda_device_list list = { 0 };
|
||||
struct irda_device_info *discoveries;
|
||||
struct irda_ias_set * ias_opt; /* IAS get/query params */
|
||||
struct ias_object * ias_obj; /* Object in IAS */
|
||||
|
@ -1337,6 +1337,7 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
|
||||
goto out;
|
||||
}
|
||||
|
||||
OVS_CB(skb)->acts_origlen = acts->orig_len;
|
||||
err = do_execute_actions(dp, skb, key,
|
||||
acts->actions, acts->actions_len);
|
||||
|
||||
|
@ -381,7 +381,7 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
|
||||
}
|
||||
|
||||
static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info,
|
||||
unsigned int hdrlen)
|
||||
unsigned int hdrlen, int actions_attrlen)
|
||||
{
|
||||
size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
|
||||
+ nla_total_size(hdrlen) /* OVS_PACKET_ATTR_PACKET */
|
||||
@ -398,7 +398,7 @@ static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info,
|
||||
|
||||
/* OVS_PACKET_ATTR_ACTIONS */
|
||||
if (upcall_info->actions_len)
|
||||
size += nla_total_size(upcall_info->actions_len);
|
||||
size += nla_total_size(actions_attrlen);
|
||||
|
||||
/* OVS_PACKET_ATTR_MRU */
|
||||
if (upcall_info->mru)
|
||||
@ -465,7 +465,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
|
||||
else
|
||||
hlen = skb->len;
|
||||
|
||||
len = upcall_msg_size(upcall_info, hlen - cutlen);
|
||||
len = upcall_msg_size(upcall_info, hlen - cutlen,
|
||||
OVS_CB(skb)->acts_origlen);
|
||||
user_skb = genlmsg_new(len, GFP_ATOMIC);
|
||||
if (!user_skb) {
|
||||
err = -ENOMEM;
|
||||
|
@ -99,11 +99,13 @@ struct datapath {
|
||||
* when a packet is received by OVS.
|
||||
* @mru: The maximum received fragement size; 0 if the packet is not
|
||||
* fragmented.
|
||||
* @acts_origlen: The netlink size of the flow actions applied to this skb.
|
||||
* @cutlen: The number of bytes from the packet end to be removed.
|
||||
*/
|
||||
struct ovs_skb_cb {
|
||||
struct vport *input_vport;
|
||||
u16 mru;
|
||||
u16 acts_origlen;
|
||||
u32 cutlen;
|
||||
};
|
||||
#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
|
||||
|
@ -223,6 +223,7 @@ void rxrpc_discard_prealloc(struct rxrpc_sock *rx)
|
||||
tail = b->call_backlog_tail;
|
||||
while (CIRC_CNT(head, tail, size) > 0) {
|
||||
struct rxrpc_call *call = b->call_backlog[tail];
|
||||
call->socket = rx;
|
||||
if (rx->discard_new_call) {
|
||||
_debug("discard %lx", call->user_call_ID);
|
||||
rx->discard_new_call(call, call->user_call_ID);
|
||||
|
@ -41,6 +41,7 @@ static int ipt_init_target(struct net *net, struct xt_entry_target *t,
|
||||
{
|
||||
struct xt_tgchk_param par;
|
||||
struct xt_target *target;
|
||||
struct ipt_entry e = {};
|
||||
int ret = 0;
|
||||
|
||||
target = xt_request_find_target(AF_INET, t->u.user.name,
|
||||
@ -52,6 +53,7 @@ static int ipt_init_target(struct net *net, struct xt_entry_target *t,
|
||||
memset(&par, 0, sizeof(par));
|
||||
par.net = net;
|
||||
par.table = table;
|
||||
par.entryinfo = &e;
|
||||
par.target = target;
|
||||
par.targinfo = t->data;
|
||||
par.hook_mask = hook;
|
||||
|
@ -205,7 +205,7 @@ static void tcf_chain_flush(struct tcf_chain *chain)
|
||||
{
|
||||
struct tcf_proto *tp;
|
||||
|
||||
if (*chain->p_filter_chain)
|
||||
if (chain->p_filter_chain)
|
||||
RCU_INIT_POINTER(*chain->p_filter_chain, NULL);
|
||||
while ((tp = rtnl_dereference(chain->filter_chain)) != NULL) {
|
||||
RCU_INIT_POINTER(chain->filter_chain, tp->next);
|
||||
|
@ -512,7 +512,9 @@ static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
|
||||
{
|
||||
addr->sa.sa_family = AF_INET6;
|
||||
addr->v6.sin6_port = port;
|
||||
addr->v6.sin6_flowinfo = 0;
|
||||
addr->v6.sin6_addr = *saddr;
|
||||
addr->v6.sin6_scope_id = 0;
|
||||
}
|
||||
|
||||
/* Compare addresses exactly.
|
||||
|
@ -258,13 +258,15 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
|
||||
arg = nlmsg_new(0, GFP_KERNEL);
|
||||
if (!arg) {
|
||||
kfree_skb(msg->rep);
|
||||
msg->rep = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
err = __tipc_nl_compat_dumpit(cmd, msg, arg);
|
||||
if (err)
|
||||
if (err) {
|
||||
kfree_skb(msg->rep);
|
||||
|
||||
msg->rep = NULL;
|
||||
}
|
||||
kfree_skb(arg);
|
||||
|
||||
return err;
|
||||
|
@ -2304,10 +2304,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
|
||||
*/
|
||||
mutex_lock(&u->iolock);
|
||||
|
||||
if (flags & MSG_PEEK)
|
||||
skip = sk_peek_offset(sk, flags);
|
||||
else
|
||||
skip = 0;
|
||||
skip = max(sk_peek_offset(sk, flags), 0);
|
||||
|
||||
do {
|
||||
int chunk;
|
||||
|
@ -879,7 +879,8 @@ bpf_object__create_maps(struct bpf_object *obj)
|
||||
size_t j;
|
||||
int err = *pfd;
|
||||
|
||||
pr_warning("failed to create map: %s\n",
|
||||
pr_warning("failed to create map (name: '%s'): %s\n",
|
||||
obj->maps[i].name,
|
||||
strerror(errno));
|
||||
for (j = 0; j < i; j++)
|
||||
zclose(obj->maps[j].fd);
|
||||
|
Loading…
Reference in New Issue
Block a user