| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * INET An implementation of the TCP/IP protocol suite for the LINUX |
|---|
| 3 | 4 | * operating system. INET is implemented using the BSD Socket |
|---|
| .. | .. |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * Authors: Many, reorganised here by |
|---|
| 9 | 10 | * Arnaldo Carvalho de Melo <acme@mandriva.com> |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or |
|---|
| 12 | | - * modify it under the terms of the GNU General Public License |
|---|
| 13 | | - * as published by the Free Software Foundation; either version |
|---|
| 14 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 15 | 11 | */ |
|---|
| 16 | 12 | #ifndef _INET_SOCK_H |
|---|
| 17 | 13 | #define _INET_SOCK_H |
|---|
| .. | .. |
|---|
| 56 | 52 | unsigned char router_alert; |
|---|
| 57 | 53 | unsigned char cipso; |
|---|
| 58 | 54 | unsigned char __pad2; |
|---|
| 59 | | - unsigned char __data[0]; |
|---|
| 55 | + unsigned char __data[]; |
|---|
| 60 | 56 | }; |
|---|
| 61 | 57 | |
|---|
| 62 | 58 | struct ip_options_rcu { |
|---|
| .. | .. |
|---|
| 111 | 107 | |
|---|
| 112 | 108 | static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb) |
|---|
| 113 | 109 | { |
|---|
| 114 | | - if (!sk->sk_mark && sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept) |
|---|
| 110 | + if (!sk->sk_mark && |
|---|
| 111 | + READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept)) |
|---|
| 115 | 112 | return skb->mark; |
|---|
| 116 | 113 | |
|---|
| 117 | 114 | return sk->sk_mark; |
|---|
| .. | .. |
|---|
| 120 | 117 | static inline int inet_request_bound_dev_if(const struct sock *sk, |
|---|
| 121 | 118 | struct sk_buff *skb) |
|---|
| 122 | 119 | { |
|---|
| 120 | + int bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); |
|---|
| 123 | 121 | #ifdef CONFIG_NET_L3_MASTER_DEV |
|---|
| 124 | 122 | struct net *net = sock_net(sk); |
|---|
| 125 | 123 | |
|---|
| 126 | | - if (!sk->sk_bound_dev_if && net->ipv4.sysctl_tcp_l3mdev_accept) |
|---|
| 124 | + if (!bound_dev_if && READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept)) |
|---|
| 127 | 125 | return l3mdev_master_ifindex_by_index(net, skb->skb_iif); |
|---|
| 128 | 126 | #endif |
|---|
| 129 | 127 | |
|---|
| 130 | | - return sk->sk_bound_dev_if; |
|---|
| 128 | + return bound_dev_if; |
|---|
| 129 | +} |
|---|
| 130 | + |
|---|
| 131 | +static inline int inet_sk_bound_l3mdev(const struct sock *sk) |
|---|
| 132 | +{ |
|---|
| 133 | +#ifdef CONFIG_NET_L3_MASTER_DEV |
|---|
| 134 | + struct net *net = sock_net(sk); |
|---|
| 135 | + |
|---|
| 136 | + if (!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept)) |
|---|
| 137 | + return l3mdev_master_ifindex_by_index(net, |
|---|
| 138 | + sk->sk_bound_dev_if); |
|---|
| 139 | +#endif |
|---|
| 140 | + |
|---|
| 141 | + return 0; |
|---|
| 142 | +} |
|---|
| 143 | + |
|---|
| 144 | +static inline bool inet_bound_dev_eq(bool l3mdev_accept, int bound_dev_if, |
|---|
| 145 | + int dif, int sdif) |
|---|
| 146 | +{ |
|---|
| 147 | + if (!bound_dev_if) |
|---|
| 148 | + return !sdif || l3mdev_accept; |
|---|
| 149 | + return bound_dev_if == dif || bound_dev_if == sdif; |
|---|
| 150 | +} |
|---|
| 151 | + |
|---|
| 152 | +static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if, |
|---|
| 153 | + int dif, int sdif) |
|---|
| 154 | +{ |
|---|
| 155 | +#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) |
|---|
| 156 | + return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept), |
|---|
| 157 | + bound_dev_if, dif, sdif); |
|---|
| 158 | +#else |
|---|
| 159 | + return inet_bound_dev_eq(true, bound_dev_if, dif, sdif); |
|---|
| 160 | +#endif |
|---|
| 131 | 161 | } |
|---|
| 132 | 162 | |
|---|
| 133 | 163 | struct inet_cork { |
|---|
| .. | .. |
|---|
| 143 | 173 | char priority; |
|---|
| 144 | 174 | __u16 gso_size; |
|---|
| 145 | 175 | u64 transmit_time; |
|---|
| 176 | + u32 mark; |
|---|
| 146 | 177 | }; |
|---|
| 147 | 178 | |
|---|
| 148 | 179 | struct inet_cork_full { |
|---|
| .. | .. |
|---|
| 207 | 238 | mc_all:1, |
|---|
| 208 | 239 | nodefrag:1; |
|---|
| 209 | 240 | __u8 bind_address_no_port:1, |
|---|
| 241 | + recverr_rfc4884:1, |
|---|
| 210 | 242 | defer_connect:1; /* Indicates that fastopen_connect is set |
|---|
| 211 | 243 | * and cookie exists so we defer connect |
|---|
| 212 | 244 | * until first data frame is written |
|---|
| .. | .. |
|---|
| 277 | 309 | memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1, |
|---|
| 278 | 310 | sk_from->sk_prot->obj_size - ancestor_size); |
|---|
| 279 | 311 | } |
|---|
| 280 | | -#if !(IS_ENABLED(CONFIG_IPV6)) |
|---|
| 281 | | -static inline void inet_sk_copy_descendant(struct sock *sk_to, |
|---|
| 282 | | - const struct sock *sk_from) |
|---|
| 283 | | -{ |
|---|
| 284 | | - __inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock)); |
|---|
| 285 | | -} |
|---|
| 286 | | -#endif |
|---|
| 287 | 312 | |
|---|
| 288 | 313 | int inet_sk_rebuild_header(struct sock *sk); |
|---|
| 289 | 314 | |
|---|
| .. | .. |
|---|
| 357 | 382 | static inline bool inet_can_nonlocal_bind(struct net *net, |
|---|
| 358 | 383 | struct inet_sock *inet) |
|---|
| 359 | 384 | { |
|---|
| 360 | | - return net->ipv4.sysctl_ip_nonlocal_bind || |
|---|
| 385 | + return READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind) || |
|---|
| 361 | 386 | inet->freebind || inet->transparent; |
|---|
| 362 | 387 | } |
|---|
| 363 | 388 | |
|---|