Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Trivial conflict in CAN, keep the net-next + the byteswap wrapper. Conflicts: drivers/net/can/usb/gs_usb.c Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -180,6 +180,7 @@ static const struct file_operations batadv_log_fops = {
|
||||
.read = batadv_log_read,
|
||||
.poll = batadv_log_poll,
|
||||
.llseek = no_llseek,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+5
-2
@@ -541,10 +541,13 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id,
|
||||
|
||||
/* Check for bugs in CAN protocol implementations using af_can.c:
|
||||
* 'rcv' will be NULL if no matching list item was found for removal.
|
||||
* As this case may potentially happen when closing a socket while
|
||||
* the notifier for removing the CAN netdev is running we just print
|
||||
* a warning here.
|
||||
*/
|
||||
if (!rcv) {
|
||||
WARN(1, "BUG: receive list entry not found for dev %s, id %03X, mask %03X\n",
|
||||
DNAME(dev), can_id, mask);
|
||||
pr_warn("can: receive list entry not found for dev %s, id %03X, mask %03X\n",
|
||||
DNAME(dev), can_id, mask);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
+39
-17
@@ -517,7 +517,7 @@ devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_l
|
||||
return test_bit(limit, &devlink->ops->reload_limits);
|
||||
}
|
||||
|
||||
static int devlink_reload_stat_put(struct sk_buff *msg, enum devlink_reload_action action,
|
||||
static int devlink_reload_stat_put(struct sk_buff *msg,
|
||||
enum devlink_reload_limit limit, u32 value)
|
||||
{
|
||||
struct nlattr *reload_stats_entry;
|
||||
@@ -526,8 +526,7 @@ static int devlink_reload_stat_put(struct sk_buff *msg, enum devlink_reload_acti
|
||||
if (!reload_stats_entry)
|
||||
return -EMSGSIZE;
|
||||
|
||||
if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, action) ||
|
||||
nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) ||
|
||||
if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) ||
|
||||
nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value))
|
||||
goto nla_put_failure;
|
||||
nla_nest_end(msg, reload_stats_entry);
|
||||
@@ -540,7 +539,7 @@ nla_put_failure:
|
||||
|
||||
static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote)
|
||||
{
|
||||
struct nlattr *reload_stats_attr;
|
||||
struct nlattr *reload_stats_attr, *act_info, *act_stats;
|
||||
int i, j, stat_idx;
|
||||
u32 value;
|
||||
|
||||
@@ -552,17 +551,29 @@ static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink
|
||||
if (!reload_stats_attr)
|
||||
return -EMSGSIZE;
|
||||
|
||||
for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) {
|
||||
/* Remote stats are shown even if not locally supported. Stats
|
||||
* of actions with unspecified limit are shown though drivers
|
||||
* don't need to register unspecified limit.
|
||||
*/
|
||||
if (!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC &&
|
||||
!devlink_reload_limit_is_supported(devlink, j))
|
||||
for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
|
||||
if ((!is_remote &&
|
||||
!devlink_reload_action_is_supported(devlink, i)) ||
|
||||
i == DEVLINK_RELOAD_ACTION_UNSPEC)
|
||||
continue;
|
||||
for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
|
||||
if ((!is_remote && !devlink_reload_action_is_supported(devlink, i)) ||
|
||||
i == DEVLINK_RELOAD_ACTION_UNSPEC ||
|
||||
act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO);
|
||||
if (!act_info)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i))
|
||||
goto action_info_nest_cancel;
|
||||
act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS);
|
||||
if (!act_stats)
|
||||
goto action_info_nest_cancel;
|
||||
|
||||
for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) {
|
||||
/* Remote stats are shown even if not locally supported.
|
||||
* Stats of actions with unspecified limit are shown
|
||||
* though drivers don't need to register unspecified
|
||||
* limit.
|
||||
*/
|
||||
if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC &&
|
||||
!devlink_reload_limit_is_supported(devlink, j)) ||
|
||||
devlink_reload_combination_is_invalid(i, j))
|
||||
continue;
|
||||
|
||||
@@ -571,13 +582,19 @@ static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink
|
||||
value = devlink->stats.reload_stats[stat_idx];
|
||||
else
|
||||
value = devlink->stats.remote_reload_stats[stat_idx];
|
||||
if (devlink_reload_stat_put(msg, i, j, value))
|
||||
goto nla_put_failure;
|
||||
if (devlink_reload_stat_put(msg, j, value))
|
||||
goto action_stats_nest_cancel;
|
||||
}
|
||||
nla_nest_end(msg, act_stats);
|
||||
nla_nest_end(msg, act_info);
|
||||
}
|
||||
nla_nest_end(msg, reload_stats_attr);
|
||||
return 0;
|
||||
|
||||
action_stats_nest_cancel:
|
||||
nla_nest_cancel(msg, act_stats);
|
||||
action_info_nest_cancel:
|
||||
nla_nest_cancel(msg, act_info);
|
||||
nla_put_failure:
|
||||
nla_nest_cancel(msg, reload_stats_attr);
|
||||
return -EMSGSIZE;
|
||||
@@ -755,6 +772,8 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
|
||||
goto nla_put_failure;
|
||||
|
||||
/* Hold rtnl lock while accessing port's netdev attributes. */
|
||||
rtnl_lock();
|
||||
spin_lock_bh(&devlink_port->type_lock);
|
||||
if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
|
||||
goto nla_put_failure_type_locked;
|
||||
@@ -763,9 +782,10 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
devlink_port->desired_type))
|
||||
goto nla_put_failure_type_locked;
|
||||
if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
|
||||
struct net *net = devlink_net(devlink_port->devlink);
|
||||
struct net_device *netdev = devlink_port->type_dev;
|
||||
|
||||
if (netdev &&
|
||||
if (netdev && net_eq(net, dev_net(netdev)) &&
|
||||
(nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
|
||||
netdev->ifindex) ||
|
||||
nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
|
||||
@@ -781,6 +801,7 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
goto nla_put_failure_type_locked;
|
||||
}
|
||||
spin_unlock_bh(&devlink_port->type_lock);
|
||||
rtnl_unlock();
|
||||
if (devlink_nl_port_attrs_put(msg, devlink_port))
|
||||
goto nla_put_failure;
|
||||
if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
|
||||
@@ -791,6 +812,7 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
|
||||
nla_put_failure_type_locked:
|
||||
spin_unlock_bh(&devlink_port->type_lock);
|
||||
rtnl_unlock();
|
||||
nla_put_failure:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
return -EMSGSIZE;
|
||||
|
||||
@@ -99,9 +99,14 @@ void gro_cells_destroy(struct gro_cells *gcells)
|
||||
struct gro_cell *cell = per_cpu_ptr(gcells->cells, i);
|
||||
|
||||
napi_disable(&cell->napi);
|
||||
netif_napi_del(&cell->napi);
|
||||
__netif_napi_del(&cell->napi);
|
||||
__skb_queue_purge(&cell->napi_skbs);
|
||||
}
|
||||
/* This barrier is needed because netpoll could access dev->napi_list
|
||||
* under rcu protection.
|
||||
*/
|
||||
synchronize_net();
|
||||
|
||||
free_percpu(gcells->cells);
|
||||
gcells->cells = NULL;
|
||||
}
|
||||
|
||||
+1
-1
@@ -4562,7 +4562,7 @@ struct sk_buff *sock_dequeue_err_skb(struct sock *sk)
|
||||
if (skb && (skb_next = skb_peek(q))) {
|
||||
icmp_next = is_icmp_err_skb(skb_next);
|
||||
if (icmp_next)
|
||||
sk->sk_err = SKB_EXT_ERR(skb_next)->ee.ee_origin;
|
||||
sk->sk_err = SKB_EXT_ERR(skb_next)->ee.ee_errno;
|
||||
}
|
||||
spin_unlock_irqrestore(&q->lock, flags);
|
||||
|
||||
|
||||
+1
-1
@@ -427,7 +427,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk,
|
||||
|
||||
if (__inet_inherit_port(sk, newsk) < 0)
|
||||
goto put_and_exit;
|
||||
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
|
||||
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL);
|
||||
if (*own_req)
|
||||
ireq->ireq_opt = NULL;
|
||||
else
|
||||
|
||||
+1
-1
@@ -533,7 +533,7 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
|
||||
dccp_done(newsk);
|
||||
goto out;
|
||||
}
|
||||
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
|
||||
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL);
|
||||
/* Clone pktoptions received with SYN, if we own the req */
|
||||
if (*own_req && ireq->pktopts) {
|
||||
newnp->pktoptions = skb_clone(ireq->pktopts, GFP_ATOMIC);
|
||||
|
||||
@@ -787,7 +787,7 @@ static void reqsk_queue_hash_req(struct request_sock *req,
|
||||
timer_setup(&req->rsk_timer, reqsk_timer_handler, TIMER_PINNED);
|
||||
mod_timer(&req->rsk_timer, jiffies + timeout);
|
||||
|
||||
inet_ehash_insert(req_to_sk(req), NULL);
|
||||
inet_ehash_insert(req_to_sk(req), NULL, NULL);
|
||||
/* before letting lookups find us, make sure all req fields
|
||||
* are committed to memory and refcnt initialized.
|
||||
*/
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#include <net/addrconf.h>
|
||||
#include <net/inet_connection_sock.h>
|
||||
#include <net/inet_hashtables.h>
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
#include <net/inet6_hashtables.h>
|
||||
#endif
|
||||
#include <net/secure_seq.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/tcp.h>
|
||||
@@ -508,10 +511,52 @@ static u32 inet_sk_port_offset(const struct sock *sk)
|
||||
inet->inet_dport);
|
||||
}
|
||||
|
||||
/* insert a socket into ehash, and eventually remove another one
|
||||
* (The another one can be a SYN_RECV or TIMEWAIT
|
||||
/* Searches for an exsiting socket in the ehash bucket list.
|
||||
* Returns true if found, false otherwise.
|
||||
*/
|
||||
bool inet_ehash_insert(struct sock *sk, struct sock *osk)
|
||||
static bool inet_ehash_lookup_by_sk(struct sock *sk,
|
||||
struct hlist_nulls_head *list)
|
||||
{
|
||||
const __portpair ports = INET_COMBINED_PORTS(sk->sk_dport, sk->sk_num);
|
||||
const int sdif = sk->sk_bound_dev_if;
|
||||
const int dif = sk->sk_bound_dev_if;
|
||||
const struct hlist_nulls_node *node;
|
||||
struct net *net = sock_net(sk);
|
||||
struct sock *esk;
|
||||
|
||||
INET_ADDR_COOKIE(acookie, sk->sk_daddr, sk->sk_rcv_saddr);
|
||||
|
||||
sk_nulls_for_each_rcu(esk, node, list) {
|
||||
if (esk->sk_hash != sk->sk_hash)
|
||||
continue;
|
||||
if (sk->sk_family == AF_INET) {
|
||||
if (unlikely(INET_MATCH(esk, net, acookie,
|
||||
sk->sk_daddr,
|
||||
sk->sk_rcv_saddr,
|
||||
ports, dif, sdif))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
else if (sk->sk_family == AF_INET6) {
|
||||
if (unlikely(INET6_MATCH(esk, net,
|
||||
&sk->sk_v6_daddr,
|
||||
&sk->sk_v6_rcv_saddr,
|
||||
ports, dif, sdif))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Insert a socket into ehash, and eventually remove another one
|
||||
* (The another one can be a SYN_RECV or TIMEWAIT)
|
||||
* If an existing socket already exists, socket sk is not inserted,
|
||||
* and sets found_dup_sk parameter to true.
|
||||
*/
|
||||
bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk)
|
||||
{
|
||||
struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
|
||||
struct hlist_nulls_head *list;
|
||||
@@ -530,16 +575,23 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk)
|
||||
if (osk) {
|
||||
WARN_ON_ONCE(sk->sk_hash != osk->sk_hash);
|
||||
ret = sk_nulls_del_node_init_rcu(osk);
|
||||
} else if (found_dup_sk) {
|
||||
*found_dup_sk = inet_ehash_lookup_by_sk(sk, list);
|
||||
if (*found_dup_sk)
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
__sk_nulls_add_node_rcu(sk, list);
|
||||
|
||||
spin_unlock(lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool inet_ehash_nolisten(struct sock *sk, struct sock *osk)
|
||||
bool inet_ehash_nolisten(struct sock *sk, struct sock *osk, bool *found_dup_sk)
|
||||
{
|
||||
bool ok = inet_ehash_insert(sk, osk);
|
||||
bool ok = inet_ehash_insert(sk, osk, found_dup_sk);
|
||||
|
||||
if (ok) {
|
||||
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
|
||||
@@ -583,7 +635,7 @@ int __inet_hash(struct sock *sk, struct sock *osk)
|
||||
int err = 0;
|
||||
|
||||
if (sk->sk_state != TCP_LISTEN) {
|
||||
inet_ehash_nolisten(sk, osk);
|
||||
inet_ehash_nolisten(sk, osk, NULL);
|
||||
return 0;
|
||||
}
|
||||
WARN_ON(!sk_unhashed(sk));
|
||||
@@ -679,7 +731,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
|
||||
tb = inet_csk(sk)->icsk_bind_hash;
|
||||
spin_lock_bh(&head->lock);
|
||||
if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
|
||||
inet_ehash_nolisten(sk, NULL);
|
||||
inet_ehash_nolisten(sk, NULL, NULL);
|
||||
spin_unlock_bh(&head->lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -758,7 +810,7 @@ ok:
|
||||
inet_bind_hash(sk, tb, port);
|
||||
if (sk_unhashed(sk)) {
|
||||
inet_sk(sk)->inet_sport = htons(port);
|
||||
inet_ehash_nolisten(sk, (struct sock *)tw);
|
||||
inet_ehash_nolisten(sk, (struct sock *)tw, NULL);
|
||||
}
|
||||
if (tw)
|
||||
inet_twsk_bind_unhash(tw, hinfo);
|
||||
|
||||
@@ -198,6 +198,11 @@ static void tcp_reinit_congestion_control(struct sock *sk,
|
||||
icsk->icsk_ca_setsockopt = 1;
|
||||
memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
|
||||
|
||||
if (ca->flags & TCP_CONG_NEEDS_ECN)
|
||||
INET_ECN_xmit(sk);
|
||||
else
|
||||
INET_ECN_dontxmit(sk);
|
||||
|
||||
if (!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
|
||||
tcp_init_congestion_control(sk);
|
||||
}
|
||||
|
||||
+22
-6
@@ -980,17 +980,22 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
|
||||
|
||||
skb = tcp_make_synack(sk, dst, req, foc, synack_type, syn_skb);
|
||||
|
||||
tos = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ?
|
||||
tcp_rsk(req)->syn_tos : inet_sk(sk)->tos;
|
||||
|
||||
if (skb) {
|
||||
__tcp_v4_send_check(skb, ireq->ir_loc_addr, ireq->ir_rmt_addr);
|
||||
|
||||
tos = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ?
|
||||
tcp_rsk(req)->syn_tos & ~INET_ECN_MASK :
|
||||
inet_sk(sk)->tos;
|
||||
|
||||
if (!INET_ECN_is_capable(tos) &&
|
||||
tcp_bpf_ca_needs_ecn((struct sock *)req))
|
||||
tos |= INET_ECN_ECT_0;
|
||||
|
||||
rcu_read_lock();
|
||||
err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr,
|
||||
ireq->ir_rmt_addr,
|
||||
rcu_dereference(ireq->ireq_opt),
|
||||
tos & ~INET_ECN_MASK);
|
||||
tos);
|
||||
rcu_read_unlock();
|
||||
err = net_xmit_eval(err);
|
||||
}
|
||||
@@ -1498,6 +1503,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
|
||||
bool *own_req)
|
||||
{
|
||||
struct inet_request_sock *ireq;
|
||||
bool found_dup_sk = false;
|
||||
struct inet_sock *newinet;
|
||||
struct tcp_sock *newtp;
|
||||
struct sock *newsk;
|
||||
@@ -1575,12 +1581,22 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
|
||||
|
||||
if (__inet_inherit_port(sk, newsk) < 0)
|
||||
goto put_and_exit;
|
||||
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
|
||||
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash),
|
||||
&found_dup_sk);
|
||||
if (likely(*own_req)) {
|
||||
tcp_move_syn(newtp, req);
|
||||
ireq->ireq_opt = NULL;
|
||||
} else {
|
||||
newinet->inet_opt = NULL;
|
||||
if (!req_unhash && found_dup_sk) {
|
||||
/* This code path should only be executed in the
|
||||
* syncookie case only
|
||||
*/
|
||||
bh_unlock_sock(newsk);
|
||||
sock_put(newsk);
|
||||
newsk = NULL;
|
||||
} else {
|
||||
newinet->inet_opt = NULL;
|
||||
}
|
||||
}
|
||||
return newsk;
|
||||
|
||||
|
||||
+17
-9
@@ -306,7 +306,9 @@ static int ip6addrlbl_del(struct net *net,
|
||||
/* add default label */
|
||||
static int __net_init ip6addrlbl_net_init(struct net *net)
|
||||
{
|
||||
int err = 0;
|
||||
struct ip6addrlbl_entry *p = NULL;
|
||||
struct hlist_node *n;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
ADDRLABEL(KERN_DEBUG "%s\n", __func__);
|
||||
@@ -315,14 +317,20 @@ static int __net_init ip6addrlbl_net_init(struct net *net)
|
||||
INIT_HLIST_HEAD(&net->ipv6.ip6addrlbl_table.head);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) {
|
||||
int ret = ip6addrlbl_add(net,
|
||||
ip6addrlbl_init_table[i].prefix,
|
||||
ip6addrlbl_init_table[i].prefixlen,
|
||||
0,
|
||||
ip6addrlbl_init_table[i].label, 0);
|
||||
/* XXX: should we free all rules when we catch an error? */
|
||||
if (ret && (!err || err != -ENOMEM))
|
||||
err = ret;
|
||||
err = ip6addrlbl_add(net,
|
||||
ip6addrlbl_init_table[i].prefix,
|
||||
ip6addrlbl_init_table[i].prefixlen,
|
||||
0,
|
||||
ip6addrlbl_init_table[i].label, 0);
|
||||
if (err)
|
||||
goto err_ip6addrlbl_add;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_ip6addrlbl_add:
|
||||
hlist_for_each_entry_safe(p, n, &net->ipv6.ip6addrlbl_table.head, list) {
|
||||
hlist_del_rcu(&p->list);
|
||||
kfree_rcu(p, rcu);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
+21
-5
@@ -527,15 +527,20 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
|
||||
if (np->repflow && ireq->pktopts)
|
||||
fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));
|
||||
|
||||
tclass = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ?
|
||||
tcp_rsk(req)->syn_tos & ~INET_ECN_MASK :
|
||||
np->tclass;
|
||||
|
||||
if (!INET_ECN_is_capable(tclass) &&
|
||||
tcp_bpf_ca_needs_ecn((struct sock *)req))
|
||||
tclass |= INET_ECN_ECT_0;
|
||||
|
||||
rcu_read_lock();
|
||||
opt = ireq->ipv6_opt;
|
||||
tclass = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ?
|
||||
tcp_rsk(req)->syn_tos : np->tclass;
|
||||
if (!opt)
|
||||
opt = rcu_dereference(np->opt);
|
||||
err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt,
|
||||
tclass & ~INET_ECN_MASK,
|
||||
sk->sk_priority);
|
||||
tclass, sk->sk_priority);
|
||||
rcu_read_unlock();
|
||||
err = net_xmit_eval(err);
|
||||
}
|
||||
@@ -1193,6 +1198,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
|
||||
const struct ipv6_pinfo *np = tcp_inet6_sk(sk);
|
||||
struct ipv6_txoptions *opt;
|
||||
struct inet_sock *newinet;
|
||||
bool found_dup_sk = false;
|
||||
struct tcp_sock *newtp;
|
||||
struct sock *newsk;
|
||||
#ifdef CONFIG_TCP_MD5SIG
|
||||
@@ -1368,7 +1374,8 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
|
||||
tcp_done(newsk);
|
||||
goto out;
|
||||
}
|
||||
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
|
||||
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash),
|
||||
&found_dup_sk);
|
||||
if (*own_req) {
|
||||
tcp_move_syn(newtp, req);
|
||||
|
||||
@@ -1383,6 +1390,15 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
|
||||
skb_set_owner_r(newnp->pktoptions, newsk);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!req_unhash && found_dup_sk) {
|
||||
/* This code path should only be executed in the
|
||||
* syncookie case only
|
||||
*/
|
||||
bh_unlock_sock(newsk);
|
||||
sock_put(newsk);
|
||||
newsk = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return newsk;
|
||||
|
||||
+2
-2
@@ -1645,7 +1645,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
|
||||
}
|
||||
|
||||
/* Create the new socket */
|
||||
nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC, 0);
|
||||
nsk = iucv_sock_alloc(NULL, sk->sk_protocol, GFP_ATOMIC, 0);
|
||||
if (!nsk) {
|
||||
err = pr_iucv->path_sever(path, user_data);
|
||||
iucv_path_free(path);
|
||||
@@ -1851,7 +1851,7 @@ static int afiucv_hs_callback_syn(struct sock *sk, struct sk_buff *skb)
|
||||
goto out;
|
||||
}
|
||||
|
||||
nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC, 0);
|
||||
nsk = iucv_sock_alloc(NULL, sk->sk_protocol, GFP_ATOMIC, 0);
|
||||
bh_lock_sock(sk);
|
||||
if ((sk->sk_state != IUCV_LISTEN) ||
|
||||
sk_acceptq_is_full(sk) ||
|
||||
|
||||
+2
-3
@@ -543,9 +543,8 @@ create_msk:
|
||||
fallback = true;
|
||||
} else if (subflow_req->mp_join) {
|
||||
mptcp_get_options(skb, &mp_opt);
|
||||
if (!mp_opt.mp_join ||
|
||||
!mptcp_can_accept_new_subflow(subflow_req->msk) ||
|
||||
!subflow_hmac_valid(req, &mp_opt)) {
|
||||
if (!mp_opt.mp_join || !subflow_hmac_valid(req, &mp_opt) ||
|
||||
!mptcp_can_accept_new_subflow(subflow_req->msk)) {
|
||||
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
|
||||
fallback = true;
|
||||
}
|
||||
|
||||
@@ -958,14 +958,13 @@ static int dec_ttl_exception_handler(struct datapath *dp, struct sk_buff *skb,
|
||||
{
|
||||
/* The first action is always 'OVS_DEC_TTL_ATTR_ARG'. */
|
||||
struct nlattr *dec_ttl_arg = nla_data(attr);
|
||||
int rem = nla_len(attr);
|
||||
|
||||
if (nla_len(dec_ttl_arg)) {
|
||||
struct nlattr *actions = nla_next(dec_ttl_arg, &rem);
|
||||
struct nlattr *actions = nla_data(dec_ttl_arg);
|
||||
|
||||
if (actions)
|
||||
return clone_execute(dp, skb, key, 0, actions, rem,
|
||||
last, false);
|
||||
return clone_execute(dp, skb, key, 0, nla_data(actions),
|
||||
nla_len(actions), last, false);
|
||||
}
|
||||
consume_skb(skb);
|
||||
return 0;
|
||||
|
||||
@@ -2503,28 +2503,42 @@ static int validate_and_copy_dec_ttl(struct net *net,
|
||||
__be16 eth_type, __be16 vlan_tci,
|
||||
u32 mpls_label_count, bool log)
|
||||
{
|
||||
int start, err;
|
||||
u32 nested = true;
|
||||
const struct nlattr *attrs[OVS_DEC_TTL_ATTR_MAX + 1];
|
||||
int start, action_start, err, rem;
|
||||
const struct nlattr *a, *actions;
|
||||
|
||||
if (!nla_len(attr))
|
||||
return ovs_nla_add_action(sfa, OVS_ACTION_ATTR_DEC_TTL,
|
||||
NULL, 0, log);
|
||||
memset(attrs, 0, sizeof(attrs));
|
||||
nla_for_each_nested(a, attr, rem) {
|
||||
int type = nla_type(a);
|
||||
|
||||
/* Ignore unknown attributes to be future proof. */
|
||||
if (type > OVS_DEC_TTL_ATTR_MAX)
|
||||
continue;
|
||||
|
||||
if (!type || attrs[type])
|
||||
return -EINVAL;
|
||||
|
||||
attrs[type] = a;
|
||||
}
|
||||
|
||||
actions = attrs[OVS_DEC_TTL_ATTR_ACTION];
|
||||
if (rem || !actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN))
|
||||
return -EINVAL;
|
||||
|
||||
start = add_nested_action_start(sfa, OVS_ACTION_ATTR_DEC_TTL, log);
|
||||
if (start < 0)
|
||||
return start;
|
||||
|
||||
err = ovs_nla_add_action(sfa, OVS_DEC_TTL_ATTR_ACTION, &nested,
|
||||
sizeof(nested), log);
|
||||
action_start = add_nested_action_start(sfa, OVS_DEC_TTL_ATTR_ACTION, log);
|
||||
if (action_start < 0)
|
||||
return start;
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = __ovs_nla_copy_actions(net, attr, key, sfa, eth_type,
|
||||
err = __ovs_nla_copy_actions(net, actions, key, sfa, eth_type,
|
||||
vlan_tci, mpls_label_count, log);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
add_nested_action_end(*sfa, action_start);
|
||||
add_nested_action_end(*sfa, start);
|
||||
return 0;
|
||||
}
|
||||
@@ -3487,20 +3501,42 @@ out:
|
||||
static int dec_ttl_action_to_attr(const struct nlattr *attr,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
int err = 0, rem = nla_len(attr);
|
||||
struct nlattr *start;
|
||||
struct nlattr *start, *action_start;
|
||||
const struct nlattr *a;
|
||||
int err = 0, rem;
|
||||
|
||||
start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_DEC_TTL);
|
||||
|
||||
if (!start)
|
||||
return -EMSGSIZE;
|
||||
|
||||
err = ovs_nla_put_actions(nla_data(attr), rem, skb);
|
||||
if (err)
|
||||
nla_nest_cancel(skb, start);
|
||||
else
|
||||
nla_nest_end(skb, start);
|
||||
nla_for_each_attr(a, nla_data(attr), nla_len(attr), rem) {
|
||||
switch (nla_type(a)) {
|
||||
case OVS_DEC_TTL_ATTR_ACTION:
|
||||
|
||||
action_start = nla_nest_start_noflag(skb, OVS_DEC_TTL_ATTR_ACTION);
|
||||
if (!action_start) {
|
||||
err = -EMSGSIZE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = ovs_nla_put_actions(nla_data(a), nla_len(a), skb);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
nla_nest_end(skb, action_start);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Ignore all other option to be future compatible */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nla_nest_end(skb, start);
|
||||
return 0;
|
||||
|
||||
out:
|
||||
nla_nest_cancel(skb, start);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,8 +94,8 @@
|
||||
|
||||
/*
|
||||
Assumptions:
|
||||
- If the device has no dev->header_ops, there is no LL header visible
|
||||
above the device. In this case, its hard_header_len should be 0.
|
||||
- If the device has no dev->header_ops->create, there is no LL header
|
||||
visible above the device. In this case, its hard_header_len should be 0.
|
||||
The device may prepend its own header internally. In this case, its
|
||||
needed_headroom should be set to the space needed for it to add its
|
||||
internal header.
|
||||
@@ -109,26 +109,26 @@
|
||||
On receive:
|
||||
-----------
|
||||
|
||||
Incoming, dev->header_ops != NULL
|
||||
Incoming, dev_has_header(dev) == true
|
||||
mac_header -> ll header
|
||||
data -> data
|
||||
|
||||
Outgoing, dev->header_ops != NULL
|
||||
Outgoing, dev_has_header(dev) == true
|
||||
mac_header -> ll header
|
||||
data -> ll header
|
||||
|
||||
Incoming, dev->header_ops == NULL
|
||||
Incoming, dev_has_header(dev) == false
|
||||
mac_header -> data
|
||||
However drivers often make it point to the ll header.
|
||||
This is incorrect because the ll header should be invisible to us.
|
||||
data -> data
|
||||
|
||||
Outgoing, dev->header_ops == NULL
|
||||
Outgoing, dev_has_header(dev) == false
|
||||
mac_header -> data. ll header is invisible to us.
|
||||
data -> data
|
||||
|
||||
Resume
|
||||
If dev->header_ops == NULL we are unable to restore the ll header,
|
||||
If dev_has_header(dev) == false we are unable to restore the ll header,
|
||||
because it is invisible to us.
|
||||
|
||||
|
||||
@@ -2083,7 +2083,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
|
||||
skb->dev = dev;
|
||||
|
||||
if (dev->header_ops) {
|
||||
if (dev_has_header(dev)) {
|
||||
/* The device has an explicit notion of ll header,
|
||||
* exported to higher levels.
|
||||
*
|
||||
@@ -2212,7 +2212,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
if (!net_eq(dev_net(dev), sock_net(sk)))
|
||||
goto drop;
|
||||
|
||||
if (dev->header_ops) {
|
||||
if (dev_has_header(dev)) {
|
||||
if (sk->sk_type != SOCK_DGRAM)
|
||||
skb_push(skb, skb->data - skb_mac_header(skb));
|
||||
else if (skb->pkt_type == PACKET_OUTGOING) {
|
||||
|
||||
@@ -96,10 +96,19 @@ static void rose_loopback_timer(struct timer_list *unused)
|
||||
}
|
||||
|
||||
if (frametype == ROSE_CALL_REQUEST) {
|
||||
if ((dev = rose_dev_get(dest)) != NULL) {
|
||||
if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0)
|
||||
kfree_skb(skb);
|
||||
} else {
|
||||
if (!rose_loopback_neigh->dev) {
|
||||
kfree_skb(skb);
|
||||
continue;
|
||||
}
|
||||
|
||||
dev = rose_dev_get(dest);
|
||||
if (!dev) {
|
||||
kfree_skb(skb);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0) {
|
||||
dev_put(dev);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1262,6 +1262,8 @@ void tls_device_offload_cleanup_rx(struct sock *sk)
|
||||
if (tls_ctx->tx_conf != TLS_HW) {
|
||||
dev_put(netdev);
|
||||
tls_ctx->netdev = NULL;
|
||||
} else {
|
||||
set_bit(TLS_RX_DEV_CLOSED, &tls_ctx->flags);
|
||||
}
|
||||
out:
|
||||
up_read(&device_offload_lock);
|
||||
@@ -1291,7 +1293,8 @@ static int tls_device_down(struct net_device *netdev)
|
||||
if (ctx->tx_conf == TLS_HW)
|
||||
netdev->tlsdev_ops->tls_dev_del(netdev, ctx,
|
||||
TLS_OFFLOAD_CTX_DIR_TX);
|
||||
if (ctx->rx_conf == TLS_HW)
|
||||
if (ctx->rx_conf == TLS_HW &&
|
||||
!test_bit(TLS_RX_DEV_CLOSED, &ctx->flags))
|
||||
netdev->tlsdev_ops->tls_dev_del(netdev, ctx,
|
||||
TLS_OFFLOAD_CTX_DIR_RX);
|
||||
WRITE_ONCE(ctx->netdev, NULL);
|
||||
|
||||
@@ -1294,6 +1294,12 @@ static struct sk_buff *tls_wait_data(struct sock *sk, struct sk_psock *psock,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!skb_queue_empty(&sk->sk_receive_queue)) {
|
||||
__strp_unpause(&ctx->strp);
|
||||
if (ctx->recv_pkt)
|
||||
return ctx->recv_pkt;
|
||||
}
|
||||
|
||||
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -841,8 +841,10 @@ void virtio_transport_release(struct vsock_sock *vsk)
|
||||
virtio_transport_free_pkt(pkt);
|
||||
}
|
||||
|
||||
if (remove_sock)
|
||||
if (remove_sock) {
|
||||
sock_set_flag(sk, SOCK_DONE);
|
||||
vsock_remove_sock(vsk);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(virtio_transport_release);
|
||||
|
||||
@@ -1132,8 +1134,8 @@ void virtio_transport_recv_pkt(struct virtio_transport *t,
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
/* Check if sk has been released before lock_sock */
|
||||
if (sk->sk_shutdown == SHUTDOWN_MASK) {
|
||||
/* Check if sk has been closed before lock_sock */
|
||||
if (sock_flag(sk, SOCK_DONE)) {
|
||||
(void)virtio_transport_reset_no_sock(t, pkt);
|
||||
release_sock(sk);
|
||||
sock_put(sk);
|
||||
|
||||
Reference in New Issue
Block a user