mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
"This looks like a lot but it's a mixture of regression fixes as well
as fixes for longer standing issues.
1) Fix on-channel cancellation in mac80211, from Johannes Berg.
2) Handle CHECKSUM_COMPLETE properly in xt_TCPMSS netfilter xtables
module, from Eric Dumazet.
3) Avoid infinite loop in UDP SO_REUSEPORT logic, also from Eric
Dumazet.
4) Avoid a NULL deref if we try to set SO_REUSEPORT after a socket is
bound, from Craig Gallek.
5) GRO key comparisons don't take lightweight tunnels into account,
from Jesse Gross.
6) Fix struct pid leak via SCM credentials in AF_UNIX, from Eric
Dumazet.
7) We need to set the rtnl_link_ops of ipv6 SIT tunnels before we
register them, otherwise the NEWLINK netlink message is missing
the proper attributes. From Thadeu Lima de Souza Cascardo.
8) Several Spectrum chip bug fixes for mlxsw switch driver, from Ido
Schimmel
9) Handle fragments properly in ipv4 easly socket demux, from Eric
Dumazet.
10) Don't ignore the ifindex key specifier on ipv6 output route
lookups, from Paolo Abeni"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (128 commits)
tcp: avoid cwnd undo after receiving ECN
irda: fix a potential use-after-free in ircomm_param_request
net: tg3: avoid uninitialized variable warning
net: nb8800: avoid uninitialized variable warning
net: vxge: avoid unused function warnings
net: bgmac: clarify CONFIG_BCMA dependency
net: hp100: remove unnecessary #ifdefs
net: davinci_cpdma: use dma_addr_t for DMA address
ipv6/udp: use sticky pktinfo egress ifindex on connect()
ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail()
netlink: not trim skb for mmaped socket when dump
vxlan: fix a out of bounds access in __vxlan_find_mac
net: dsa: mv88e6xxx: fix port VLAN maps
fib_trie: Fix shift by 32 in fib_table_lookup
net: moxart: use correct accessors for DMA memory
ipv4: ipconfig: avoid unused ic_proto_used symbol
bnxt_en: Fix crash in bnxt_free_tx_skbs() during tx timeout.
bnxt_en: Exclude rx_drop_pkts hw counter from the stack's rx_dropped counter.
bnxt_en: Ring free response from close path should use completion ring
net_sched: drr: check for NULL pointer in drr_dequeue
...
This commit is contained in:
commit
34229b2774
154 changed files with 1402 additions and 843 deletions
|
|
@ -307,6 +307,9 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
|
|||
|
||||
/* check that it's our buffer */
|
||||
if (lowpan_is_ipv6(*skb_network_header(skb))) {
|
||||
/* Pull off the 1-byte of 6lowpan header. */
|
||||
skb_pull(skb, 1);
|
||||
|
||||
/* Copy the packet so that the IPv6 header is
|
||||
* properly aligned.
|
||||
*/
|
||||
|
|
@ -317,6 +320,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
|
|||
|
||||
local_skb->protocol = htons(ETH_P_IPV6);
|
||||
local_skb->pkt_type = PACKET_HOST;
|
||||
local_skb->dev = dev;
|
||||
|
||||
skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
|
||||
|
||||
|
|
@ -335,6 +339,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
|
|||
if (!local_skb)
|
||||
goto drop;
|
||||
|
||||
local_skb->dev = dev;
|
||||
|
||||
ret = iphc_decompress(local_skb, dev, chan);
|
||||
if (ret < 0) {
|
||||
kfree_skb(local_skb);
|
||||
|
|
@ -343,7 +349,6 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
|
|||
|
||||
local_skb->protocol = htons(ETH_P_IPV6);
|
||||
local_skb->pkt_type = PACKET_HOST;
|
||||
local_skb->dev = dev;
|
||||
|
||||
if (give_skb_to_upper(local_skb, dev)
|
||||
!= NET_RX_SUCCESS) {
|
||||
|
|
|
|||
|
|
@ -688,21 +688,29 @@ static u8 update_white_list(struct hci_request *req)
|
|||
* command to remove it from the controller.
|
||||
*/
|
||||
list_for_each_entry(b, &hdev->le_white_list, list) {
|
||||
struct hci_cp_le_del_from_white_list cp;
|
||||
/* If the device is neither in pend_le_conns nor
|
||||
* pend_le_reports then remove it from the whitelist.
|
||||
*/
|
||||
if (!hci_pend_le_action_lookup(&hdev->pend_le_conns,
|
||||
&b->bdaddr, b->bdaddr_type) &&
|
||||
!hci_pend_le_action_lookup(&hdev->pend_le_reports,
|
||||
&b->bdaddr, b->bdaddr_type)) {
|
||||
struct hci_cp_le_del_from_white_list cp;
|
||||
|
||||
if (hci_pend_le_action_lookup(&hdev->pend_le_conns,
|
||||
&b->bdaddr, b->bdaddr_type) ||
|
||||
hci_pend_le_action_lookup(&hdev->pend_le_reports,
|
||||
&b->bdaddr, b->bdaddr_type)) {
|
||||
white_list_entries++;
|
||||
cp.bdaddr_type = b->bdaddr_type;
|
||||
bacpy(&cp.bdaddr, &b->bdaddr);
|
||||
|
||||
hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST,
|
||||
sizeof(cp), &cp);
|
||||
continue;
|
||||
}
|
||||
|
||||
cp.bdaddr_type = b->bdaddr_type;
|
||||
bacpy(&cp.bdaddr, &b->bdaddr);
|
||||
if (hci_find_irk_by_addr(hdev, &b->bdaddr, b->bdaddr_type)) {
|
||||
/* White list can not be used with RPAs */
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST,
|
||||
sizeof(cp), &cp);
|
||||
white_list_entries++;
|
||||
}
|
||||
|
||||
/* Since all no longer valid white list entries have been
|
||||
|
|
|
|||
|
|
@ -197,10 +197,20 @@ int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
|
|||
chan->sport = psm;
|
||||
err = 0;
|
||||
} else {
|
||||
u16 p;
|
||||
u16 p, start, end, incr;
|
||||
|
||||
if (chan->src_type == BDADDR_BREDR) {
|
||||
start = L2CAP_PSM_DYN_START;
|
||||
end = L2CAP_PSM_AUTO_END;
|
||||
incr = 2;
|
||||
} else {
|
||||
start = L2CAP_PSM_LE_DYN_START;
|
||||
end = L2CAP_PSM_LE_DYN_END;
|
||||
incr = 1;
|
||||
}
|
||||
|
||||
err = -EINVAL;
|
||||
for (p = 0x1001; p < 0x1100; p += 2)
|
||||
for (p = start; p <= end; p += incr)
|
||||
if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
|
||||
chan->psm = cpu_to_le16(p);
|
||||
chan->sport = cpu_to_le16(p);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ static int l2cap_validate_bredr_psm(u16 psm)
|
|||
return -EINVAL;
|
||||
|
||||
/* Restrict usage of well-known PSMs */
|
||||
if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE))
|
||||
if (psm < L2CAP_PSM_DYN_START && !capable(CAP_NET_BIND_SERVICE))
|
||||
return -EACCES;
|
||||
|
||||
return 0;
|
||||
|
|
@ -67,11 +67,11 @@ static int l2cap_validate_bredr_psm(u16 psm)
|
|||
static int l2cap_validate_le_psm(u16 psm)
|
||||
{
|
||||
/* Valid LE_PSM ranges are defined only until 0x00ff */
|
||||
if (psm > 0x00ff)
|
||||
if (psm > L2CAP_PSM_LE_DYN_END)
|
||||
return -EINVAL;
|
||||
|
||||
/* Restrict fixed, SIG assigned PSM values to CAP_NET_BIND_SERVICE */
|
||||
if (psm <= 0x007f && !capable(CAP_NET_BIND_SERVICE))
|
||||
if (psm < L2CAP_PSM_LE_DYN_START && !capable(CAP_NET_BIND_SERVICE))
|
||||
return -EACCES;
|
||||
|
||||
return 0;
|
||||
|
|
@ -125,6 +125,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
|
|||
goto done;
|
||||
}
|
||||
|
||||
bacpy(&chan->src, &la.l2_bdaddr);
|
||||
chan->src_type = la.l2_bdaddr_type;
|
||||
|
||||
if (la.l2_cid)
|
||||
err = l2cap_add_scid(chan, __le16_to_cpu(la.l2_cid));
|
||||
else
|
||||
|
|
@ -156,9 +159,6 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
|
|||
break;
|
||||
}
|
||||
|
||||
bacpy(&chan->src, &la.l2_bdaddr);
|
||||
chan->src_type = la.l2_bdaddr_type;
|
||||
|
||||
if (chan->psm && bdaddr_type_is_le(chan->src_type))
|
||||
chan->mode = L2CAP_MODE_LE_FLOWCTL;
|
||||
|
||||
|
|
|
|||
|
|
@ -1072,22 +1072,6 @@ static void smp_notify_keys(struct l2cap_conn *conn)
|
|||
hcon->dst_type = smp->remote_irk->addr_type;
|
||||
queue_work(hdev->workqueue, &conn->id_addr_update_work);
|
||||
}
|
||||
|
||||
/* When receiving an indentity resolving key for
|
||||
* a remote device that does not use a resolvable
|
||||
* private address, just remove the key so that
|
||||
* it is possible to use the controller white
|
||||
* list for scanning.
|
||||
*
|
||||
* Userspace will have been told to not store
|
||||
* this key at this point. So it is safe to
|
||||
* just remove it.
|
||||
*/
|
||||
if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
|
||||
list_del_rcu(&smp->remote_irk->list);
|
||||
kfree_rcu(smp->remote_irk, rcu);
|
||||
smp->remote_irk = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (smp->csrk) {
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ static struct notifier_block br_device_notifier = {
|
|||
.notifier_call = br_device_event
|
||||
};
|
||||
|
||||
/* called with RTNL */
|
||||
static int br_switchdev_event(struct notifier_block *unused,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
|
|
@ -130,7 +131,6 @@ static int br_switchdev_event(struct notifier_block *unused,
|
|||
struct switchdev_notifier_fdb_info *fdb_info;
|
||||
int err = NOTIFY_DONE;
|
||||
|
||||
rtnl_lock();
|
||||
p = br_port_get_rtnl(dev);
|
||||
if (!p)
|
||||
goto out;
|
||||
|
|
@ -155,7 +155,6 @@ static int br_switchdev_event(struct notifier_block *unused,
|
|||
}
|
||||
|
||||
out:
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4351,6 +4351,7 @@ static void gro_list_prepare(struct napi_struct *napi, struct sk_buff *skb)
|
|||
|
||||
diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
|
||||
diffs |= p->vlan_tci ^ skb->vlan_tci;
|
||||
diffs |= skb_metadata_dst_cmp(p, skb);
|
||||
if (maclen == ETH_HLEN)
|
||||
diffs |= compare_ether_header(skb_mac_header(p),
|
||||
skb_mac_header(skb));
|
||||
|
|
@ -4548,10 +4549,12 @@ static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
|
|||
break;
|
||||
|
||||
case GRO_MERGED_FREE:
|
||||
if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD)
|
||||
if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) {
|
||||
skb_dst_drop(skb);
|
||||
kmem_cache_free(skbuff_head_cache, skb);
|
||||
else
|
||||
} else {
|
||||
__kfree_skb(skb);
|
||||
}
|
||||
break;
|
||||
|
||||
case GRO_HELD:
|
||||
|
|
|
|||
|
|
@ -93,10 +93,17 @@ static struct sock_reuseport *reuseport_grow(struct sock_reuseport *reuse)
|
|||
* @sk2: Socket belonging to the existing reuseport group.
|
||||
* May return ENOMEM and not add socket to group under memory pressure.
|
||||
*/
|
||||
int reuseport_add_sock(struct sock *sk, const struct sock *sk2)
|
||||
int reuseport_add_sock(struct sock *sk, struct sock *sk2)
|
||||
{
|
||||
struct sock_reuseport *reuse;
|
||||
|
||||
if (!rcu_access_pointer(sk2->sk_reuseport_cb)) {
|
||||
int err = reuseport_alloc(sk2);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
spin_lock_bh(&reuseport_lock);
|
||||
reuse = rcu_dereference_protected(sk2->sk_reuseport_cb,
|
||||
lockdep_is_held(&reuseport_lock)),
|
||||
|
|
|
|||
|
|
@ -353,6 +353,7 @@ config INET_ESP
|
|||
select CRYPTO_CBC
|
||||
select CRYPTO_SHA1
|
||||
select CRYPTO_DES
|
||||
select CRYPTO_ECHAINIV
|
||||
---help---
|
||||
Support for IPsec ESP.
|
||||
|
||||
|
|
|
|||
|
|
@ -1394,9 +1394,10 @@ found:
|
|||
struct fib_info *fi = fa->fa_info;
|
||||
int nhsel, err;
|
||||
|
||||
if ((index >= (1ul << fa->fa_slen)) &&
|
||||
((BITS_PER_LONG > KEYLENGTH) || (fa->fa_slen != KEYLENGTH)))
|
||||
continue;
|
||||
if ((BITS_PER_LONG > KEYLENGTH) || (fa->fa_slen < KEYLENGTH)) {
|
||||
if (index >= (1ul << fa->fa_slen))
|
||||
continue;
|
||||
}
|
||||
if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos)
|
||||
continue;
|
||||
if (fi->fib_dead)
|
||||
|
|
|
|||
|
|
@ -361,13 +361,20 @@ struct sock *inet_diag_find_one_icsk(struct net *net,
|
|||
req->id.idiag_dport, req->id.idiag_src[0],
|
||||
req->id.idiag_sport, req->id.idiag_if);
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
else if (req->sdiag_family == AF_INET6)
|
||||
sk = inet6_lookup(net, hashinfo,
|
||||
(struct in6_addr *)req->id.idiag_dst,
|
||||
req->id.idiag_dport,
|
||||
(struct in6_addr *)req->id.idiag_src,
|
||||
req->id.idiag_sport,
|
||||
req->id.idiag_if);
|
||||
else if (req->sdiag_family == AF_INET6) {
|
||||
if (ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_dst) &&
|
||||
ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_src))
|
||||
sk = inet_lookup(net, hashinfo, req->id.idiag_dst[3],
|
||||
req->id.idiag_dport, req->id.idiag_src[3],
|
||||
req->id.idiag_sport, req->id.idiag_if);
|
||||
else
|
||||
sk = inet6_lookup(net, hashinfo,
|
||||
(struct in6_addr *)req->id.idiag_dst,
|
||||
req->id.idiag_dport,
|
||||
(struct in6_addr *)req->id.idiag_src,
|
||||
req->id.idiag_sport,
|
||||
req->id.idiag_if);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
|
|
|||
|
|
@ -661,6 +661,7 @@ int ip_defrag(struct net *net, struct sk_buff *skb, u32 user)
|
|||
struct ipq *qp;
|
||||
|
||||
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
|
||||
skb_orphan(skb);
|
||||
|
||||
/* Lookup (or create) queue header */
|
||||
qp = ip_find(net, ip_hdr(skb), user, vif);
|
||||
|
|
|
|||
|
|
@ -316,7 +316,10 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
|
|||
const struct iphdr *iph = ip_hdr(skb);
|
||||
struct rtable *rt;
|
||||
|
||||
if (sysctl_ip_early_demux && !skb_dst(skb) && !skb->sk) {
|
||||
if (sysctl_ip_early_demux &&
|
||||
!skb_dst(skb) &&
|
||||
!skb->sk &&
|
||||
!ip_is_fragment(iph)) {
|
||||
const struct net_protocol *ipprot;
|
||||
int protocol = iph->protocol;
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,11 @@ static char dhcp_client_identifier[253] __initdata;
|
|||
|
||||
/* Persistent data: */
|
||||
|
||||
#ifdef IPCONFIG_DYNAMIC
|
||||
static int ic_proto_used; /* Protocol used, if any */
|
||||
#else
|
||||
#define ic_proto_used 0
|
||||
#endif
|
||||
static __be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
|
||||
static u8 ic_domain[64]; /* DNS (not NIS) domain name */
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb,
|
|||
{
|
||||
int err;
|
||||
|
||||
skb_orphan(skb);
|
||||
|
||||
local_bh_disable();
|
||||
err = ip_defrag(net, skb, user);
|
||||
local_bh_enable();
|
||||
|
|
|
|||
|
|
@ -279,6 +279,7 @@
|
|||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/ioctls.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <net/busy_poll.h>
|
||||
|
||||
int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
|
||||
|
|
@ -2638,6 +2639,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
|
|||
const struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
u32 now = tcp_time_stamp;
|
||||
unsigned int start;
|
||||
u64 rate64;
|
||||
u32 rate;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
|
@ -2703,15 +2705,17 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
|
|||
info->tcpi_total_retrans = tp->total_retrans;
|
||||
|
||||
rate = READ_ONCE(sk->sk_pacing_rate);
|
||||
info->tcpi_pacing_rate = rate != ~0U ? rate : ~0ULL;
|
||||
rate64 = rate != ~0U ? rate : ~0ULL;
|
||||
put_unaligned(rate64, &info->tcpi_pacing_rate);
|
||||
|
||||
rate = READ_ONCE(sk->sk_max_pacing_rate);
|
||||
info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL;
|
||||
rate64 = rate != ~0U ? rate : ~0ULL;
|
||||
put_unaligned(rate64, &info->tcpi_max_pacing_rate);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_irq(&tp->syncp);
|
||||
info->tcpi_bytes_acked = tp->bytes_acked;
|
||||
info->tcpi_bytes_received = tp->bytes_received;
|
||||
put_unaligned(tp->bytes_acked, &info->tcpi_bytes_acked);
|
||||
put_unaligned(tp->bytes_received, &info->tcpi_bytes_received);
|
||||
} while (u64_stats_fetch_retry_irq(&tp->syncp, start));
|
||||
info->tcpi_segs_out = tp->segs_out;
|
||||
info->tcpi_segs_in = tp->segs_in;
|
||||
|
|
|
|||
|
|
@ -2164,8 +2164,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
|
|||
{
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct sk_buff *skb;
|
||||
int cnt, oldcnt;
|
||||
int err;
|
||||
int cnt, oldcnt, lost;
|
||||
unsigned int mss;
|
||||
/* Use SACK to deduce losses of new sequences sent during recovery */
|
||||
const u32 loss_high = tcp_is_sack(tp) ? tp->snd_nxt : tp->high_seq;
|
||||
|
|
@ -2205,9 +2204,10 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
|
|||
break;
|
||||
|
||||
mss = tcp_skb_mss(skb);
|
||||
err = tcp_fragment(sk, skb, (packets - oldcnt) * mss,
|
||||
mss, GFP_ATOMIC);
|
||||
if (err < 0)
|
||||
/* If needed, chop off the prefix to mark as lost. */
|
||||
lost = (packets - oldcnt) * mss;
|
||||
if (lost < skb->len &&
|
||||
tcp_fragment(sk, skb, lost, mss, GFP_ATOMIC) < 0)
|
||||
break;
|
||||
cnt = packets;
|
||||
}
|
||||
|
|
@ -2366,8 +2366,6 @@ static void tcp_undo_cwnd_reduction(struct sock *sk, bool unmark_loss)
|
|||
tp->snd_ssthresh = tp->prior_ssthresh;
|
||||
tcp_ecn_withdraw_cwr(tp);
|
||||
}
|
||||
} else {
|
||||
tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh);
|
||||
}
|
||||
tp->snd_cwnd_stamp = tcp_time_stamp;
|
||||
tp->undo_marker = 0;
|
||||
|
|
|
|||
|
|
@ -707,7 +707,8 @@ release_sk1:
|
|||
outside socket context is ugly, certainly. What can I do?
|
||||
*/
|
||||
|
||||
static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
|
||||
static void tcp_v4_send_ack(struct net *net,
|
||||
struct sk_buff *skb, u32 seq, u32 ack,
|
||||
u32 win, u32 tsval, u32 tsecr, int oif,
|
||||
struct tcp_md5sig_key *key,
|
||||
int reply_flags, u8 tos)
|
||||
|
|
@ -722,7 +723,6 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
|
|||
];
|
||||
} rep;
|
||||
struct ip_reply_arg arg;
|
||||
struct net *net = dev_net(skb_dst(skb)->dev);
|
||||
|
||||
memset(&rep.th, 0, sizeof(struct tcphdr));
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
|
|
@ -784,7 +784,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
|
|||
struct inet_timewait_sock *tw = inet_twsk(sk);
|
||||
struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
|
||||
|
||||
tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
|
||||
tcp_v4_send_ack(sock_net(sk), skb,
|
||||
tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
|
||||
tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
|
||||
tcp_time_stamp + tcptw->tw_ts_offset,
|
||||
tcptw->tw_ts_recent,
|
||||
|
|
@ -803,8 +804,10 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
|
|||
/* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV
|
||||
* sk->sk_state == TCP_SYN_RECV -> for Fast Open.
|
||||
*/
|
||||
tcp_v4_send_ack(skb, (sk->sk_state == TCP_LISTEN) ?
|
||||
tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt,
|
||||
u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 :
|
||||
tcp_sk(sk)->snd_nxt;
|
||||
|
||||
tcp_v4_send_ack(sock_net(sk), skb, seq,
|
||||
tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd,
|
||||
tcp_time_stamp,
|
||||
req->ts_recent,
|
||||
|
|
|
|||
|
|
@ -499,6 +499,7 @@ static struct sock *udp4_lib_lookup2(struct net *net,
|
|||
struct sock *sk, *result;
|
||||
struct hlist_nulls_node *node;
|
||||
int score, badness, matches = 0, reuseport = 0;
|
||||
bool select_ok = true;
|
||||
u32 hash = 0;
|
||||
|
||||
begin:
|
||||
|
|
@ -512,14 +513,18 @@ begin:
|
|||
badness = score;
|
||||
reuseport = sk->sk_reuseport;
|
||||
if (reuseport) {
|
||||
struct sock *sk2;
|
||||
hash = udp_ehashfn(net, daddr, hnum,
|
||||
saddr, sport);
|
||||
sk2 = reuseport_select_sock(sk, hash, skb,
|
||||
sizeof(struct udphdr));
|
||||
if (sk2) {
|
||||
result = sk2;
|
||||
goto found;
|
||||
if (select_ok) {
|
||||
struct sock *sk2;
|
||||
|
||||
sk2 = reuseport_select_sock(sk, hash, skb,
|
||||
sizeof(struct udphdr));
|
||||
if (sk2) {
|
||||
result = sk2;
|
||||
select_ok = false;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
matches = 1;
|
||||
}
|
||||
|
|
@ -563,6 +568,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
|
|||
unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask);
|
||||
struct udp_hslot *hslot2, *hslot = &udptable->hash[slot];
|
||||
int score, badness, matches = 0, reuseport = 0;
|
||||
bool select_ok = true;
|
||||
u32 hash = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
|
|
@ -601,14 +607,18 @@ begin:
|
|||
badness = score;
|
||||
reuseport = sk->sk_reuseport;
|
||||
if (reuseport) {
|
||||
struct sock *sk2;
|
||||
hash = udp_ehashfn(net, daddr, hnum,
|
||||
saddr, sport);
|
||||
sk2 = reuseport_select_sock(sk, hash, skb,
|
||||
if (select_ok) {
|
||||
struct sock *sk2;
|
||||
|
||||
sk2 = reuseport_select_sock(sk, hash, skb,
|
||||
sizeof(struct udphdr));
|
||||
if (sk2) {
|
||||
result = sk2;
|
||||
goto found;
|
||||
if (sk2) {
|
||||
result = sk2;
|
||||
select_ok = false;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
matches = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ config INET6_ESP
|
|||
select CRYPTO_CBC
|
||||
select CRYPTO_SHA1
|
||||
select CRYPTO_DES
|
||||
select CRYPTO_ECHAINIV
|
||||
---help---
|
||||
Support for IPsec ESP.
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,9 @@ ipv4_connected:
|
|||
fl6.fl6_dport = inet->inet_dport;
|
||||
fl6.fl6_sport = inet->inet_sport;
|
||||
|
||||
if (!fl6.flowi6_oif)
|
||||
fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
|
||||
|
||||
if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST))
|
||||
fl6.flowi6_oif = np->mcast_oif;
|
||||
|
||||
|
|
|
|||
|
|
@ -909,6 +909,7 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,
|
|||
struct rt6_info *rt;
|
||||
#endif
|
||||
int err;
|
||||
int flags = 0;
|
||||
|
||||
/* The correct way to handle this would be to do
|
||||
* ip6_route_get_saddr, and then ip6_route_output; however,
|
||||
|
|
@ -940,10 +941,13 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,
|
|||
dst_release(*dst);
|
||||
*dst = NULL;
|
||||
}
|
||||
|
||||
if (fl6->flowi6_oif)
|
||||
flags |= RT6_LOOKUP_F_IFACE;
|
||||
}
|
||||
|
||||
if (!*dst)
|
||||
*dst = ip6_route_output(net, sk, fl6);
|
||||
*dst = ip6_route_output_flags(net, sk, fl6, flags);
|
||||
|
||||
err = (*dst)->error;
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -1183,11 +1183,10 @@ static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table
|
|||
return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
|
||||
}
|
||||
|
||||
struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
|
||||
struct flowi6 *fl6)
|
||||
struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
|
||||
struct flowi6 *fl6, int flags)
|
||||
{
|
||||
struct dst_entry *dst;
|
||||
int flags = 0;
|
||||
bool any_src;
|
||||
|
||||
dst = l3mdev_rt6_dst_by_oif(net, fl6);
|
||||
|
|
@ -1208,7 +1207,7 @@ struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
|
|||
|
||||
return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output);
|
||||
}
|
||||
EXPORT_SYMBOL(ip6_route_output);
|
||||
EXPORT_SYMBOL_GPL(ip6_route_output_flags);
|
||||
|
||||
struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -201,14 +201,14 @@ static int ipip6_tunnel_create(struct net_device *dev)
|
|||
if ((__force u16)t->parms.i_flags & SIT_ISATAP)
|
||||
dev->priv_flags |= IFF_ISATAP;
|
||||
|
||||
dev->rtnl_link_ops = &sit_link_ops;
|
||||
|
||||
err = register_netdevice(dev);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
ipip6_tunnel_clone_6rd(dev, sitn);
|
||||
|
||||
dev->rtnl_link_ops = &sit_link_ops;
|
||||
|
||||
dev_hold(dev);
|
||||
|
||||
ipip6_tunnel_link(sitn, t);
|
||||
|
|
|
|||
|
|
@ -257,6 +257,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,
|
|||
struct sock *sk, *result;
|
||||
struct hlist_nulls_node *node;
|
||||
int score, badness, matches = 0, reuseport = 0;
|
||||
bool select_ok = true;
|
||||
u32 hash = 0;
|
||||
|
||||
begin:
|
||||
|
|
@ -270,14 +271,18 @@ begin:
|
|||
badness = score;
|
||||
reuseport = sk->sk_reuseport;
|
||||
if (reuseport) {
|
||||
struct sock *sk2;
|
||||
hash = udp6_ehashfn(net, daddr, hnum,
|
||||
saddr, sport);
|
||||
sk2 = reuseport_select_sock(sk, hash, skb,
|
||||
sizeof(struct udphdr));
|
||||
if (sk2) {
|
||||
result = sk2;
|
||||
goto found;
|
||||
if (select_ok) {
|
||||
struct sock *sk2;
|
||||
|
||||
sk2 = reuseport_select_sock(sk, hash, skb,
|
||||
sizeof(struct udphdr));
|
||||
if (sk2) {
|
||||
result = sk2;
|
||||
select_ok = false;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
matches = 1;
|
||||
}
|
||||
|
|
@ -321,6 +326,7 @@ struct sock *__udp6_lib_lookup(struct net *net,
|
|||
unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask);
|
||||
struct udp_hslot *hslot2, *hslot = &udptable->hash[slot];
|
||||
int score, badness, matches = 0, reuseport = 0;
|
||||
bool select_ok = true;
|
||||
u32 hash = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
|
|
@ -358,14 +364,18 @@ begin:
|
|||
badness = score;
|
||||
reuseport = sk->sk_reuseport;
|
||||
if (reuseport) {
|
||||
struct sock *sk2;
|
||||
hash = udp6_ehashfn(net, daddr, hnum,
|
||||
saddr, sport);
|
||||
sk2 = reuseport_select_sock(sk, hash, skb,
|
||||
if (select_ok) {
|
||||
struct sock *sk2;
|
||||
|
||||
sk2 = reuseport_select_sock(sk, hash, skb,
|
||||
sizeof(struct udphdr));
|
||||
if (sk2) {
|
||||
result = sk2;
|
||||
goto found;
|
||||
if (sk2) {
|
||||
result = sk2;
|
||||
select_ok = false;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
matches = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,11 +134,10 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
|
|||
return -1;
|
||||
}
|
||||
skb_put(skb, count);
|
||||
pr_debug("%s(), skb->len=%d\n", __func__, skb->len);
|
||||
|
||||
spin_unlock_irqrestore(&self->spinlock, flags);
|
||||
|
||||
pr_debug("%s(), skb->len=%d\n", __func__ , skb->len);
|
||||
|
||||
if (flush) {
|
||||
/* ircomm_tty_do_softint will take care of the rest */
|
||||
schedule_work(&self->tqueue);
|
||||
|
|
|
|||
|
|
@ -708,6 +708,9 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
|
|||
if (!addr || addr->sa_family != AF_IUCV)
|
||||
return -EINVAL;
|
||||
|
||||
if (addr_len < sizeof(struct sockaddr_iucv))
|
||||
return -EINVAL;
|
||||
|
||||
lock_sock(sk);
|
||||
if (sk->sk_state != IUCV_OPEN) {
|
||||
err = -EBADFD;
|
||||
|
|
|
|||
|
|
@ -1733,7 +1733,6 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
|
|||
if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
|
||||
continue;
|
||||
sdata->u.ibss.last_scan_completed = jiffies;
|
||||
ieee80211_queue_work(&local->hw, &sdata->work);
|
||||
}
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,6 +248,7 @@ static void ieee80211_restart_work(struct work_struct *work)
|
|||
|
||||
/* wait for scan work complete */
|
||||
flush_workqueue(local->workqueue);
|
||||
flush_work(&local->sched_scan_stopped_work);
|
||||
|
||||
WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
|
||||
"%s called with hardware scan in progress\n", __func__);
|
||||
|
|
@ -256,6 +257,11 @@ static void ieee80211_restart_work(struct work_struct *work)
|
|||
list_for_each_entry(sdata, &local->interfaces, list)
|
||||
flush_delayed_work(&sdata->dec_tailroom_needed_wk);
|
||||
ieee80211_scan_cancel(local);
|
||||
|
||||
/* make sure any new ROC will consider local->in_reconfig */
|
||||
flush_delayed_work(&local->roc_work);
|
||||
flush_work(&local->hw_roc_done);
|
||||
|
||||
ieee80211_reconfig(local);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1370,17 +1370,6 @@ out:
|
|||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list)
|
||||
if (ieee80211_vif_is_mesh(&sdata->vif) &&
|
||||
ieee80211_sdata_running(sdata))
|
||||
ieee80211_queue_work(&local->hw, &sdata->work);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -362,14 +362,10 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
|
|||
return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
|
||||
}
|
||||
|
||||
void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
|
||||
|
||||
void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
|
||||
void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211s_stop(void);
|
||||
#else
|
||||
static inline void
|
||||
ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
|
||||
static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
|
||||
{ return false; }
|
||||
static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
|
||||
|
|
|
|||
|
|
@ -4005,8 +4005,6 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
|
|||
if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
|
||||
ieee80211_queue_work(&sdata->local->hw,
|
||||
&sdata->u.mgd.monitor_work);
|
||||
/* and do all the other regular work too */
|
||||
ieee80211_queue_work(&sdata->local->hw, &sdata->work);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -252,14 +252,11 @@ static bool ieee80211_recalc_sw_work(struct ieee80211_local *local,
|
|||
static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
|
||||
unsigned long start_time)
|
||||
{
|
||||
struct ieee80211_local *local = roc->sdata->local;
|
||||
|
||||
if (WARN_ON(roc->notified))
|
||||
return;
|
||||
|
||||
roc->start_time = start_time;
|
||||
roc->started = true;
|
||||
roc->hw_begun = true;
|
||||
|
||||
if (roc->mgmt_tx_cookie) {
|
||||
if (!WARN_ON(!roc->frame)) {
|
||||
|
|
@ -274,9 +271,6 @@ static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
|
|||
}
|
||||
|
||||
roc->notified = true;
|
||||
|
||||
if (!local->ops->remain_on_channel)
|
||||
ieee80211_recalc_sw_work(local, start_time);
|
||||
}
|
||||
|
||||
static void ieee80211_hw_roc_start(struct work_struct *work)
|
||||
|
|
@ -291,6 +285,7 @@ static void ieee80211_hw_roc_start(struct work_struct *work)
|
|||
if (!roc->started)
|
||||
break;
|
||||
|
||||
roc->hw_begun = true;
|
||||
ieee80211_handle_roc_started(roc, local->hw_roc_start_time);
|
||||
}
|
||||
|
||||
|
|
@ -413,6 +408,10 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
|
|||
return;
|
||||
}
|
||||
|
||||
/* defer roc if driver is not started (i.e. during reconfig) */
|
||||
if (local->in_reconfig)
|
||||
return;
|
||||
|
||||
roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work,
|
||||
list);
|
||||
|
||||
|
|
@ -534,8 +533,10 @@ ieee80211_coalesce_hw_started_roc(struct ieee80211_local *local,
|
|||
* begin, otherwise they'll both be marked properly by the work
|
||||
* struct that runs once the driver notifies us of the beginning
|
||||
*/
|
||||
if (cur_roc->hw_begun)
|
||||
if (cur_roc->hw_begun) {
|
||||
new_roc->hw_begun = true;
|
||||
ieee80211_handle_roc_started(new_roc, now);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -658,6 +659,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
|||
queued = true;
|
||||
roc->on_channel = tmp->on_channel;
|
||||
ieee80211_handle_roc_started(roc, now);
|
||||
ieee80211_recalc_sw_work(local, now);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -314,6 +314,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
|
|||
bool was_scanning = local->scanning;
|
||||
struct cfg80211_scan_request *scan_req;
|
||||
struct ieee80211_sub_if_data *scan_sdata;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
||||
lockdep_assert_held(&local->mtx);
|
||||
|
||||
|
|
@ -373,7 +374,16 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
|
|||
|
||||
ieee80211_mlme_notify_scan_completed(local);
|
||||
ieee80211_ibss_notify_scan_completed(local);
|
||||
ieee80211_mesh_notify_scan_completed(local);
|
||||
|
||||
/* Requeue all the work that might have been ignored while
|
||||
* the scan was in progress; if there was none this will
|
||||
* just be a no-op for the particular interface.
|
||||
*/
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
if (ieee80211_sdata_running(sdata))
|
||||
ieee80211_queue_work(&sdata->local->hw, &sdata->work);
|
||||
}
|
||||
|
||||
if (was_scanning)
|
||||
ieee80211_start_next_roc(local);
|
||||
}
|
||||
|
|
@ -1213,6 +1223,14 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
|
|||
|
||||
trace_api_sched_scan_stopped(local);
|
||||
|
||||
/*
|
||||
* this shouldn't really happen, so for simplicity
|
||||
* simply ignore it, and let mac80211 reconfigure
|
||||
* the sched scan later on.
|
||||
*/
|
||||
if (local->in_reconfig)
|
||||
return;
|
||||
|
||||
schedule_work(&local->sched_scan_stopped_work);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
|
||||
|
|
|
|||
|
|
@ -1453,7 +1453,7 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
|
|||
|
||||
more_data = ieee80211_sta_ps_more_data(sta, ignored_acs, reason, driver_release_tids);
|
||||
|
||||
if (reason == IEEE80211_FRAME_RELEASE_PSPOLL)
|
||||
if (driver_release_tids && reason == IEEE80211_FRAME_RELEASE_PSPOLL)
|
||||
driver_release_tids =
|
||||
BIT(find_highest_prio_tid(driver_release_tids));
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
|
|||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
int ac;
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) {
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This skb 'survived' a round-trip through the driver, and
|
||||
* hopefully the driver didn't mangle it too badly. However,
|
||||
|
|
|
|||
|
|
@ -2043,16 +2043,26 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
|||
*/
|
||||
if (sched_scan_req->n_scan_plans > 1 ||
|
||||
__ieee80211_request_sched_scan_start(sched_scan_sdata,
|
||||
sched_scan_req))
|
||||
sched_scan_req)) {
|
||||
RCU_INIT_POINTER(local->sched_scan_sdata, NULL);
|
||||
RCU_INIT_POINTER(local->sched_scan_req, NULL);
|
||||
sched_scan_stopped = true;
|
||||
}
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
if (sched_scan_stopped)
|
||||
cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy);
|
||||
|
||||
wake_up:
|
||||
local->in_reconfig = false;
|
||||
barrier();
|
||||
if (local->in_reconfig) {
|
||||
local->in_reconfig = false;
|
||||
barrier();
|
||||
|
||||
/* Restart deferred ROCs */
|
||||
mutex_lock(&local->mtx);
|
||||
ieee80211_start_next_roc(local);
|
||||
mutex_unlock(&local->mtx);
|
||||
}
|
||||
|
||||
if (local->monitors == local->open_count && local->monitors > 0)
|
||||
ieee80211_add_virtual_monitor(local);
|
||||
|
|
|
|||
|
|
@ -164,8 +164,6 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
|
|||
};
|
||||
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
|
||||
|
||||
if (e.cidr == 0)
|
||||
return -EINVAL;
|
||||
if (adt == IPSET_TEST)
|
||||
e.cidr = HOST_MASK;
|
||||
|
||||
|
|
@ -377,8 +375,6 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
|
|||
};
|
||||
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
|
||||
|
||||
if (e.cidr == 0)
|
||||
return -EINVAL;
|
||||
if (adt == IPSET_TEST)
|
||||
e.cidr = HOST_MASK;
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,21 @@ EXPORT_SYMBOL_GPL(nf_conntrack_locks);
|
|||
__cacheline_aligned_in_smp DEFINE_SPINLOCK(nf_conntrack_expect_lock);
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_expect_lock);
|
||||
|
||||
static __read_mostly spinlock_t nf_conntrack_locks_all_lock;
|
||||
static __read_mostly bool nf_conntrack_locks_all;
|
||||
|
||||
void nf_conntrack_lock(spinlock_t *lock) __acquires(lock)
|
||||
{
|
||||
spin_lock(lock);
|
||||
while (unlikely(nf_conntrack_locks_all)) {
|
||||
spin_unlock(lock);
|
||||
spin_lock(&nf_conntrack_locks_all_lock);
|
||||
spin_unlock(&nf_conntrack_locks_all_lock);
|
||||
spin_lock(lock);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_lock);
|
||||
|
||||
static void nf_conntrack_double_unlock(unsigned int h1, unsigned int h2)
|
||||
{
|
||||
h1 %= CONNTRACK_LOCKS;
|
||||
|
|
@ -82,12 +97,12 @@ static bool nf_conntrack_double_lock(struct net *net, unsigned int h1,
|
|||
h1 %= CONNTRACK_LOCKS;
|
||||
h2 %= CONNTRACK_LOCKS;
|
||||
if (h1 <= h2) {
|
||||
spin_lock(&nf_conntrack_locks[h1]);
|
||||
nf_conntrack_lock(&nf_conntrack_locks[h1]);
|
||||
if (h1 != h2)
|
||||
spin_lock_nested(&nf_conntrack_locks[h2],
|
||||
SINGLE_DEPTH_NESTING);
|
||||
} else {
|
||||
spin_lock(&nf_conntrack_locks[h2]);
|
||||
nf_conntrack_lock(&nf_conntrack_locks[h2]);
|
||||
spin_lock_nested(&nf_conntrack_locks[h1],
|
||||
SINGLE_DEPTH_NESTING);
|
||||
}
|
||||
|
|
@ -102,16 +117,19 @@ static void nf_conntrack_all_lock(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONNTRACK_LOCKS; i++)
|
||||
spin_lock_nested(&nf_conntrack_locks[i], i);
|
||||
spin_lock(&nf_conntrack_locks_all_lock);
|
||||
nf_conntrack_locks_all = true;
|
||||
|
||||
for (i = 0; i < CONNTRACK_LOCKS; i++) {
|
||||
spin_lock(&nf_conntrack_locks[i]);
|
||||
spin_unlock(&nf_conntrack_locks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void nf_conntrack_all_unlock(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONNTRACK_LOCKS; i++)
|
||||
spin_unlock(&nf_conntrack_locks[i]);
|
||||
nf_conntrack_locks_all = false;
|
||||
spin_unlock(&nf_conntrack_locks_all_lock);
|
||||
}
|
||||
|
||||
unsigned int nf_conntrack_htable_size __read_mostly;
|
||||
|
|
@ -757,7 +775,7 @@ restart:
|
|||
hash = hash_bucket(_hash, net);
|
||||
for (; i < net->ct.htable_size; i++) {
|
||||
lockp = &nf_conntrack_locks[hash % CONNTRACK_LOCKS];
|
||||
spin_lock(lockp);
|
||||
nf_conntrack_lock(lockp);
|
||||
if (read_seqcount_retry(&net->ct.generation, sequence)) {
|
||||
spin_unlock(lockp);
|
||||
goto restart;
|
||||
|
|
@ -1382,7 +1400,7 @@ get_next_corpse(struct net *net, int (*iter)(struct nf_conn *i, void *data),
|
|||
for (; *bucket < net->ct.htable_size; (*bucket)++) {
|
||||
lockp = &nf_conntrack_locks[*bucket % CONNTRACK_LOCKS];
|
||||
local_bh_disable();
|
||||
spin_lock(lockp);
|
||||
nf_conntrack_lock(lockp);
|
||||
if (*bucket < net->ct.htable_size) {
|
||||
hlist_nulls_for_each_entry(h, n, &net->ct.hash[*bucket], hnnode) {
|
||||
if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
|
|||
}
|
||||
local_bh_disable();
|
||||
for (i = 0; i < net->ct.htable_size; i++) {
|
||||
spin_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
|
||||
nf_conntrack_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
|
||||
if (i < net->ct.htable_size) {
|
||||
hlist_nulls_for_each_entry(h, nn, &net->ct.hash[i], hnnode)
|
||||
unhelp(h, me);
|
||||
|
|
|
|||
|
|
@ -840,7 +840,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
for (; cb->args[0] < net->ct.htable_size; cb->args[0]++) {
|
||||
restart:
|
||||
lockp = &nf_conntrack_locks[cb->args[0] % CONNTRACK_LOCKS];
|
||||
spin_lock(lockp);
|
||||
nf_conntrack_lock(lockp);
|
||||
if (cb->args[0] >= net->ct.htable_size) {
|
||||
spin_unlock(lockp);
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -224,12 +224,12 @@ static int __init nf_tables_netdev_init(void)
|
|||
|
||||
nft_register_chain_type(&nft_filter_chain_netdev);
|
||||
ret = register_pernet_subsys(&nf_tables_netdev_net_ops);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
nft_unregister_chain_type(&nft_filter_chain_netdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
register_netdevice_notifier(&nf_tables_netdev_notifier);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit nf_tables_netdev_exit(void)
|
||||
|
|
|
|||
|
|
@ -307,12 +307,12 @@ static void ctnl_untimeout(struct net *net, struct ctnl_timeout *timeout)
|
|||
|
||||
local_bh_disable();
|
||||
for (i = 0; i < net->ct.htable_size; i++) {
|
||||
spin_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
|
||||
nf_conntrack_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
|
||||
if (i < net->ct.htable_size) {
|
||||
hlist_nulls_for_each_entry(h, nn, &net->ct.hash[i], hnnode)
|
||||
untimeout(h, timeout);
|
||||
}
|
||||
spin_unlock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
|
||||
nf_conntrack_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
|
||||
}
|
||||
local_bh_enable();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,16 +46,14 @@ static void nft_byteorder_eval(const struct nft_expr *expr,
|
|||
switch (priv->op) {
|
||||
case NFT_BYTEORDER_NTOH:
|
||||
for (i = 0; i < priv->len / 8; i++) {
|
||||
src64 = get_unaligned_be64(&src[i]);
|
||||
src64 = be64_to_cpu((__force __be64)src64);
|
||||
src64 = get_unaligned((u64 *)&src[i]);
|
||||
put_unaligned_be64(src64, &dst[i]);
|
||||
}
|
||||
break;
|
||||
case NFT_BYTEORDER_HTON:
|
||||
for (i = 0; i < priv->len / 8; i++) {
|
||||
src64 = get_unaligned_be64(&src[i]);
|
||||
src64 = (__force u64)cpu_to_be64(src64);
|
||||
put_unaligned_be64(src64, &dst[i]);
|
||||
put_unaligned(src64, (u64 *)&dst[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
|
|||
NF_CT_LABELS_MAX_SIZE - size);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
case NFT_CT_BYTES: /* fallthrough */
|
||||
case NFT_CT_PKTS: {
|
||||
const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
|
||||
|
|
@ -138,7 +139,6 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
|
|||
memcpy(dest, &count, sizeof(count));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ tcpmss_tg6(struct sk_buff *skb, const struct xt_action_param *par)
|
|||
{
|
||||
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
|
||||
u8 nexthdr;
|
||||
__be16 frag_off;
|
||||
__be16 frag_off, oldlen, newlen;
|
||||
int tcphoff;
|
||||
int ret;
|
||||
|
||||
|
|
@ -244,7 +244,12 @@ tcpmss_tg6(struct sk_buff *skb, const struct xt_action_param *par)
|
|||
return NF_DROP;
|
||||
if (ret > 0) {
|
||||
ipv6h = ipv6_hdr(skb);
|
||||
ipv6h->payload_len = htons(ntohs(ipv6h->payload_len) + ret);
|
||||
oldlen = ipv6h->payload_len;
|
||||
newlen = htons(ntohs(oldlen) + ret);
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||
skb->csum = csum_add(csum_sub(skb->csum, oldlen),
|
||||
newlen);
|
||||
ipv6h->payload_len = newlen;
|
||||
}
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2831,7 +2831,8 @@ static int netlink_dump(struct sock *sk)
|
|||
* reasonable static buffer based on the expected largest dump of a
|
||||
* single netdev. The outcome is MSG_TRUNC error.
|
||||
*/
|
||||
skb_reserve(skb, skb_tailroom(skb) - alloc_size);
|
||||
if (!netlink_rx_is_mmaped(sk))
|
||||
skb_reserve(skb, skb_tailroom(skb) - alloc_size);
|
||||
netlink_skb_set_owner_r(skb, sk);
|
||||
|
||||
len = cb->dump(skb, cb);
|
||||
|
|
|
|||
|
|
@ -1095,17 +1095,6 @@ static unsigned int rfkill_fop_poll(struct file *file, poll_table *wait)
|
|||
return res;
|
||||
}
|
||||
|
||||
static bool rfkill_readable(struct rfkill_data *data)
|
||||
{
|
||||
bool r;
|
||||
|
||||
mutex_lock(&data->mtx);
|
||||
r = !list_empty(&data->events);
|
||||
mutex_unlock(&data->mtx);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
|
|
@ -1122,8 +1111,11 @@ static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
|
|||
goto out;
|
||||
}
|
||||
mutex_unlock(&data->mtx);
|
||||
/* since we re-check and it just compares pointers,
|
||||
* using !list_empty() without locking isn't a problem
|
||||
*/
|
||||
ret = wait_event_interruptible(data->read_wait,
|
||||
rfkill_readable(data));
|
||||
!list_empty(&data->events));
|
||||
mutex_lock(&data->mtx);
|
||||
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -403,6 +403,8 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch)
|
|||
if (len <= cl->deficit) {
|
||||
cl->deficit -= len;
|
||||
skb = qdisc_dequeue_peeked(cl->qdisc);
|
||||
if (unlikely(skb == NULL))
|
||||
goto out;
|
||||
if (cl->qdisc->q.qlen == 0)
|
||||
list_del(&cl->alist);
|
||||
|
||||
|
|
|
|||
|
|
@ -935,15 +935,22 @@ static struct sctp_association *__sctp_lookup_association(
|
|||
struct sctp_transport **pt)
|
||||
{
|
||||
struct sctp_transport *t;
|
||||
struct sctp_association *asoc = NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
t = sctp_addrs_lookup_transport(net, local, peer);
|
||||
if (!t || t->dead)
|
||||
return NULL;
|
||||
if (!t || !sctp_transport_hold(t))
|
||||
goto out;
|
||||
|
||||
sctp_association_hold(t->asoc);
|
||||
asoc = t->asoc;
|
||||
sctp_association_hold(asoc);
|
||||
*pt = t;
|
||||
|
||||
return t->asoc;
|
||||
sctp_transport_put(t);
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return asoc;
|
||||
}
|
||||
|
||||
/* Look up an association. protected by RCU read lock */
|
||||
|
|
@ -955,9 +962,7 @@ struct sctp_association *sctp_lookup_association(struct net *net,
|
|||
{
|
||||
struct sctp_association *asoc;
|
||||
|
||||
rcu_read_lock();
|
||||
asoc = __sctp_lookup_association(net, laddr, paddr, transportp);
|
||||
rcu_read_unlock();
|
||||
|
||||
return asoc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,8 +165,6 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa
|
|||
list_for_each_entry_rcu(transport, &assoc->peer.transport_addr_list,
|
||||
transports) {
|
||||
addr = &transport->ipaddr;
|
||||
if (transport->dead)
|
||||
continue;
|
||||
|
||||
af = sctp_get_af_specific(addr->sa.sa_family);
|
||||
if (af->cmp_addr(addr, primary)) {
|
||||
|
|
@ -380,6 +378,8 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
|
|||
}
|
||||
|
||||
transport = (struct sctp_transport *)v;
|
||||
if (!sctp_transport_hold(transport))
|
||||
return 0;
|
||||
assoc = transport->asoc;
|
||||
epb = &assoc->base;
|
||||
sk = epb->sk;
|
||||
|
|
@ -412,6 +412,8 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
|
|||
sk->sk_rcvbuf);
|
||||
seq_printf(seq, "\n");
|
||||
|
||||
sctp_transport_put(transport);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -489,12 +491,12 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
|
|||
}
|
||||
|
||||
tsp = (struct sctp_transport *)v;
|
||||
if (!sctp_transport_hold(tsp))
|
||||
return 0;
|
||||
assoc = tsp->asoc;
|
||||
|
||||
list_for_each_entry_rcu(tsp, &assoc->peer.transport_addr_list,
|
||||
transports) {
|
||||
if (tsp->dead)
|
||||
continue;
|
||||
/*
|
||||
* The remote address (ADDR)
|
||||
*/
|
||||
|
|
@ -544,6 +546,8 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
|
|||
seq_printf(seq, "\n");
|
||||
}
|
||||
|
||||
sctp_transport_put(tsp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -259,12 +259,6 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* Is this transport really dead and just waiting around for
|
||||
* the timer to let go of the reference?
|
||||
*/
|
||||
if (transport->dead)
|
||||
goto out_unlock;
|
||||
|
||||
/* Run through the state machine. */
|
||||
error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
|
||||
SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_T3_RTX),
|
||||
|
|
@ -380,12 +374,6 @@ void sctp_generate_heartbeat_event(unsigned long data)
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* Is this structure just waiting around for us to actually
|
||||
* get destroyed?
|
||||
*/
|
||||
if (transport->dead)
|
||||
goto out_unlock;
|
||||
|
||||
error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
|
||||
SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_HEARTBEAT),
|
||||
asoc->state, asoc->ep, asoc,
|
||||
|
|
|
|||
|
|
@ -6636,6 +6636,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
|
|||
|
||||
if (cmsgs->srinfo->sinfo_flags &
|
||||
~(SCTP_UNORDERED | SCTP_ADDR_OVER |
|
||||
SCTP_SACK_IMMEDIATELY |
|
||||
SCTP_ABORT | SCTP_EOF))
|
||||
return -EINVAL;
|
||||
break;
|
||||
|
|
@ -6659,6 +6660,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
|
|||
|
||||
if (cmsgs->sinfo->snd_flags &
|
||||
~(SCTP_UNORDERED | SCTP_ADDR_OVER |
|
||||
SCTP_SACK_IMMEDIATELY |
|
||||
SCTP_ABORT | SCTP_EOF))
|
||||
return -EINVAL;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -132,8 +132,6 @@ fail:
|
|||
*/
|
||||
void sctp_transport_free(struct sctp_transport *transport)
|
||||
{
|
||||
transport->dead = 1;
|
||||
|
||||
/* Try to delete the heartbeat timer. */
|
||||
if (del_timer(&transport->hb_timer))
|
||||
sctp_transport_put(transport);
|
||||
|
|
@ -169,7 +167,7 @@ static void sctp_transport_destroy_rcu(struct rcu_head *head)
|
|||
*/
|
||||
static void sctp_transport_destroy(struct sctp_transport *transport)
|
||||
{
|
||||
if (unlikely(!transport->dead)) {
|
||||
if (unlikely(atomic_read(&transport->refcnt))) {
|
||||
WARN(1, "Attempt to destroy undead transport %p!\n", transport);
|
||||
return;
|
||||
}
|
||||
|
|
@ -296,9 +294,9 @@ void sctp_transport_route(struct sctp_transport *transport,
|
|||
}
|
||||
|
||||
/* Hold a reference to a transport. */
|
||||
void sctp_transport_hold(struct sctp_transport *transport)
|
||||
int sctp_transport_hold(struct sctp_transport *transport)
|
||||
{
|
||||
atomic_inc(&transport->refcnt);
|
||||
return atomic_add_unless(&transport->refcnt, 1, 0);
|
||||
}
|
||||
|
||||
/* Release a reference to a transport and clean up
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/list.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <net/ip_fib.h>
|
||||
#include <net/switchdev.h>
|
||||
|
||||
|
|
@ -567,7 +568,6 @@ int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(switchdev_port_obj_dump);
|
||||
|
||||
static DEFINE_MUTEX(switchdev_mutex);
|
||||
static RAW_NOTIFIER_HEAD(switchdev_notif_chain);
|
||||
|
||||
/**
|
||||
|
|
@ -582,9 +582,9 @@ int register_switchdev_notifier(struct notifier_block *nb)
|
|||
{
|
||||
int err;
|
||||
|
||||
mutex_lock(&switchdev_mutex);
|
||||
rtnl_lock();
|
||||
err = raw_notifier_chain_register(&switchdev_notif_chain, nb);
|
||||
mutex_unlock(&switchdev_mutex);
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_switchdev_notifier);
|
||||
|
|
@ -600,9 +600,9 @@ int unregister_switchdev_notifier(struct notifier_block *nb)
|
|||
{
|
||||
int err;
|
||||
|
||||
mutex_lock(&switchdev_mutex);
|
||||
rtnl_lock();
|
||||
err = raw_notifier_chain_unregister(&switchdev_notif_chain, nb);
|
||||
mutex_unlock(&switchdev_mutex);
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_switchdev_notifier);
|
||||
|
|
@ -616,16 +616,17 @@ EXPORT_SYMBOL_GPL(unregister_switchdev_notifier);
|
|||
* Call all network notifier blocks. This should be called by driver
|
||||
* when it needs to propagate hardware event.
|
||||
* Return values are same as for atomic_notifier_call_chain().
|
||||
* rtnl_lock must be held.
|
||||
*/
|
||||
int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
|
||||
struct switchdev_notifier_info *info)
|
||||
{
|
||||
int err;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
info->dev = dev;
|
||||
mutex_lock(&switchdev_mutex);
|
||||
err = raw_notifier_call_chain(&switchdev_notif_chain, val, info);
|
||||
mutex_unlock(&switchdev_mutex);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
|
||||
|
|
|
|||
|
|
@ -289,15 +289,14 @@ static void tipc_subscrb_rcv_cb(struct net *net, int conid,
|
|||
struct sockaddr_tipc *addr, void *usr_data,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
struct tipc_subscriber *subscriber = usr_data;
|
||||
struct tipc_subscriber *subscrb = usr_data;
|
||||
struct tipc_subscription *sub = NULL;
|
||||
struct tipc_net *tn = net_generic(net, tipc_net_id);
|
||||
|
||||
tipc_subscrp_create(net, (struct tipc_subscr *)buf, subscriber, &sub);
|
||||
if (sub)
|
||||
tipc_nametbl_subscribe(sub);
|
||||
else
|
||||
tipc_conn_terminate(tn->topsrv, subscriber->conid);
|
||||
if (tipc_subscrp_create(net, (struct tipc_subscr *)buf, subscrb, &sub))
|
||||
return tipc_conn_terminate(tn->topsrv, subscrb->conid);
|
||||
|
||||
tipc_nametbl_subscribe(sub);
|
||||
}
|
||||
|
||||
/* Handle one request to establish a new subscriber */
|
||||
|
|
|
|||
|
|
@ -2339,6 +2339,7 @@ again:
|
|||
|
||||
if (signal_pending(current)) {
|
||||
err = sock_intr_errno(timeo);
|
||||
scm_destroy(&scm);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -231,20 +231,22 @@ static const struct ieee80211_regdomain world_regdom = {
|
|||
/* IEEE 802.11b/g, channels 1..11 */
|
||||
REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
|
||||
/* IEEE 802.11b/g, channels 12..13. */
|
||||
REG_RULE(2467-10, 2472+10, 40, 6, 20,
|
||||
NL80211_RRF_NO_IR),
|
||||
REG_RULE(2467-10, 2472+10, 20, 6, 20,
|
||||
NL80211_RRF_NO_IR | NL80211_RRF_AUTO_BW),
|
||||
/* IEEE 802.11 channel 14 - Only JP enables
|
||||
* this and for 802.11b only */
|
||||
REG_RULE(2484-10, 2484+10, 20, 6, 20,
|
||||
NL80211_RRF_NO_IR |
|
||||
NL80211_RRF_NO_OFDM),
|
||||
/* IEEE 802.11a, channel 36..48 */
|
||||
REG_RULE(5180-10, 5240+10, 160, 6, 20,
|
||||
NL80211_RRF_NO_IR),
|
||||
REG_RULE(5180-10, 5240+10, 80, 6, 20,
|
||||
NL80211_RRF_NO_IR |
|
||||
NL80211_RRF_AUTO_BW),
|
||||
|
||||
/* IEEE 802.11a, channel 52..64 - DFS required */
|
||||
REG_RULE(5260-10, 5320+10, 160, 6, 20,
|
||||
REG_RULE(5260-10, 5320+10, 80, 6, 20,
|
||||
NL80211_RRF_NO_IR |
|
||||
NL80211_RRF_AUTO_BW |
|
||||
NL80211_RRF_DFS),
|
||||
|
||||
/* IEEE 802.11a, channel 100..144 - DFS required */
|
||||
|
|
@ -2745,7 +2747,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
|
|||
const struct ieee80211_power_rule *power_rule = NULL;
|
||||
char bw[32], cac_time[32];
|
||||
|
||||
pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)\n");
|
||||
pr_debug(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)\n");
|
||||
|
||||
for (i = 0; i < rd->n_reg_rules; i++) {
|
||||
reg_rule = &rd->reg_rules[i];
|
||||
|
|
@ -2772,7 +2774,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
|
|||
* in certain regions
|
||||
*/
|
||||
if (power_rule->max_antenna_gain)
|
||||
pr_info(" (%d KHz - %d KHz @ %s), (%d mBi, %d mBm), (%s)\n",
|
||||
pr_debug(" (%d KHz - %d KHz @ %s), (%d mBi, %d mBm), (%s)\n",
|
||||
freq_range->start_freq_khz,
|
||||
freq_range->end_freq_khz,
|
||||
bw,
|
||||
|
|
@ -2780,7 +2782,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
|
|||
power_rule->max_eirp,
|
||||
cac_time);
|
||||
else
|
||||
pr_info(" (%d KHz - %d KHz @ %s), (N/A, %d mBm), (%s)\n",
|
||||
pr_debug(" (%d KHz - %d KHz @ %s), (N/A, %d mBm), (%s)\n",
|
||||
freq_range->start_freq_khz,
|
||||
freq_range->end_freq_khz,
|
||||
bw,
|
||||
|
|
@ -2813,35 +2815,35 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
|
|||
struct cfg80211_registered_device *rdev;
|
||||
rdev = cfg80211_rdev_by_wiphy_idx(lr->wiphy_idx);
|
||||
if (rdev) {
|
||||
pr_info("Current regulatory domain updated by AP to: %c%c\n",
|
||||
pr_debug("Current regulatory domain updated by AP to: %c%c\n",
|
||||
rdev->country_ie_alpha2[0],
|
||||
rdev->country_ie_alpha2[1]);
|
||||
} else
|
||||
pr_info("Current regulatory domain intersected:\n");
|
||||
pr_debug("Current regulatory domain intersected:\n");
|
||||
} else
|
||||
pr_info("Current regulatory domain intersected:\n");
|
||||
pr_debug("Current regulatory domain intersected:\n");
|
||||
} else if (is_world_regdom(rd->alpha2)) {
|
||||
pr_info("World regulatory domain updated:\n");
|
||||
pr_debug("World regulatory domain updated:\n");
|
||||
} else {
|
||||
if (is_unknown_alpha2(rd->alpha2))
|
||||
pr_info("Regulatory domain changed to driver built-in settings (unknown country)\n");
|
||||
pr_debug("Regulatory domain changed to driver built-in settings (unknown country)\n");
|
||||
else {
|
||||
if (reg_request_cell_base(lr))
|
||||
pr_info("Regulatory domain changed to country: %c%c by Cell Station\n",
|
||||
pr_debug("Regulatory domain changed to country: %c%c by Cell Station\n",
|
||||
rd->alpha2[0], rd->alpha2[1]);
|
||||
else
|
||||
pr_info("Regulatory domain changed to country: %c%c\n",
|
||||
pr_debug("Regulatory domain changed to country: %c%c\n",
|
||||
rd->alpha2[0], rd->alpha2[1]);
|
||||
}
|
||||
}
|
||||
|
||||
pr_info(" DFS Master region: %s", reg_dfs_region_str(rd->dfs_region));
|
||||
pr_debug(" DFS Master region: %s", reg_dfs_region_str(rd->dfs_region));
|
||||
print_rd_rules(rd);
|
||||
}
|
||||
|
||||
static void print_regdomain_info(const struct ieee80211_regdomain *rd)
|
||||
{
|
||||
pr_info("Regulatory domain: %c%c\n", rd->alpha2[0], rd->alpha2[1]);
|
||||
pr_debug("Regulatory domain: %c%c\n", rd->alpha2[0], rd->alpha2[1]);
|
||||
print_rd_rules(rd);
|
||||
}
|
||||
|
||||
|
|
@ -2862,7 +2864,8 @@ static int reg_set_rd_user(const struct ieee80211_regdomain *rd,
|
|||
return -EALREADY;
|
||||
|
||||
if (!is_valid_rd(rd)) {
|
||||
pr_err("Invalid regulatory domain detected:\n");
|
||||
pr_err("Invalid regulatory domain detected: %c%c\n",
|
||||
rd->alpha2[0], rd->alpha2[1]);
|
||||
print_regdomain_info(rd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -2898,7 +2901,8 @@ static int reg_set_rd_driver(const struct ieee80211_regdomain *rd,
|
|||
return -EALREADY;
|
||||
|
||||
if (!is_valid_rd(rd)) {
|
||||
pr_err("Invalid regulatory domain detected:\n");
|
||||
pr_err("Invalid regulatory domain detected: %c%c\n",
|
||||
rd->alpha2[0], rd->alpha2[1]);
|
||||
print_regdomain_info(rd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -2956,7 +2960,8 @@ static int reg_set_rd_country_ie(const struct ieee80211_regdomain *rd,
|
|||
*/
|
||||
|
||||
if (!is_valid_rd(rd)) {
|
||||
pr_err("Invalid regulatory domain detected:\n");
|
||||
pr_err("Invalid regulatory domain detected: %c%c\n",
|
||||
rd->alpha2[0], rd->alpha2[1]);
|
||||
print_regdomain_info(rd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue