Commit 91ed1e66 authored by Paolo Abeni's avatar Paolo Abeni Committed by David S. Miller

ip/options: explicitly provide net ns to __ip_options_echo()

__ip_options_echo() uses the current network namespace, and
currently retrives it via skb->dst->dev.

This commit adds an explicit 'net' argument to __ip_options_echo()
and update all the call sites to provide it, usually via a simpler
sock_net().

After this change, __ip_options_echo() no more needs to access
skb->dst and we can drop a couple of hack to preserve such
info in the rx path.
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a1e155ec
...@@ -567,11 +567,12 @@ int ip_forward(struct sk_buff *skb); ...@@ -567,11 +567,12 @@ int ip_forward(struct sk_buff *skb);
void ip_options_build(struct sk_buff *skb, struct ip_options *opt, void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
__be32 daddr, struct rtable *rt, int is_frag); __be32 daddr, struct rtable *rt, int is_frag);
int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb, int __ip_options_echo(struct net *net, struct ip_options *dopt,
const struct ip_options *sopt); struct sk_buff *skb, const struct ip_options *sopt);
static inline int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb) static inline int ip_options_echo(struct net *net, struct ip_options *dopt,
struct sk_buff *skb)
{ {
return __ip_options_echo(dopt, skb, &IPCB(skb)->opt); return __ip_options_echo(net, dopt, skb, &IPCB(skb)->opt);
} }
void ip_options_fragment(struct sk_buff *skb); void ip_options_fragment(struct sk_buff *skb);
......
...@@ -1885,7 +1885,8 @@ extern void tcp_rack_reo_timeout(struct sock *sk); ...@@ -1885,7 +1885,8 @@ extern void tcp_rack_reo_timeout(struct sock *sk);
/* /*
* Save and compile IPv4 options, return a pointer to it * Save and compile IPv4 options, return a pointer to it
*/ */
static inline struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb) static inline struct ip_options_rcu *tcp_v4_save_options(struct net *net,
struct sk_buff *skb)
{ {
const struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt; const struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt;
struct ip_options_rcu *dopt = NULL; struct ip_options_rcu *dopt = NULL;
...@@ -1894,7 +1895,7 @@ static inline struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb) ...@@ -1894,7 +1895,7 @@ static inline struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb)
int opt_size = sizeof(*dopt) + opt->optlen; int opt_size = sizeof(*dopt) + opt->optlen;
dopt = kmalloc(opt_size, GFP_ATOMIC); dopt = kmalloc(opt_size, GFP_ATOMIC);
if (dopt && __ip_options_echo(&dopt->opt, skb, opt)) { if (dopt && __ip_options_echo(net, &dopt->opt, skb, opt)) {
kfree(dopt); kfree(dopt);
dopt = NULL; dopt = NULL;
} }
......
...@@ -412,7 +412,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) ...@@ -412,7 +412,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
int type = icmp_param->data.icmph.type; int type = icmp_param->data.icmph.type;
int code = icmp_param->data.icmph.code; int code = icmp_param->data.icmph.code;
if (ip_options_echo(&icmp_param->replyopts.opt.opt, skb)) if (ip_options_echo(net, &icmp_param->replyopts.opt.opt, skb))
return; return;
/* Needed by both icmp_global_allow and icmp_xmit_lock */ /* Needed by both icmp_global_allow and icmp_xmit_lock */
...@@ -694,7 +694,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) ...@@ -694,7 +694,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
iph->tos; iph->tos;
mark = IP4_REPLY_MARK(net, skb_in->mark); mark = IP4_REPLY_MARK(net, skb_in->mark);
if (ip_options_echo(&icmp_param.replyopts.opt.opt, skb_in)) if (ip_options_echo(net, &icmp_param.replyopts.opt.opt, skb_in))
goto out_unlock; goto out_unlock;
......
...@@ -86,8 +86,8 @@ void ip_options_build(struct sk_buff *skb, struct ip_options *opt, ...@@ -86,8 +86,8 @@ void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
* NOTE: dopt cannot point to skb. * NOTE: dopt cannot point to skb.
*/ */
int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb, int __ip_options_echo(struct net *net, struct ip_options *dopt,
const struct ip_options *sopt) struct sk_buff *skb, const struct ip_options *sopt)
{ {
unsigned char *sptr, *dptr; unsigned char *sptr, *dptr;
int soffset, doffset; int soffset, doffset;
...@@ -140,7 +140,7 @@ int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb, ...@@ -140,7 +140,7 @@ int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb,
__be32 addr; __be32 addr;
memcpy(&addr, dptr+soffset-1, 4); memcpy(&addr, dptr+soffset-1, 4);
if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_UNICAST) { if (inet_addr_type(net, addr) != RTN_UNICAST) {
dopt->ts_needtime = 1; dopt->ts_needtime = 1;
soffset += 8; soffset += 8;
} }
......
...@@ -1525,7 +1525,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, ...@@ -1525,7 +1525,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
int err; int err;
int oif; int oif;
if (__ip_options_echo(&replyopts.opt.opt, skb, sopt)) if (__ip_options_echo(net, &replyopts.opt.opt, skb, sopt))
return; return;
ipc.addr = daddr; ipc.addr = daddr;
......
...@@ -80,7 +80,8 @@ static void ip_cmsg_recv_opts(struct msghdr *msg, struct sk_buff *skb) ...@@ -80,7 +80,8 @@ static void ip_cmsg_recv_opts(struct msghdr *msg, struct sk_buff *skb)
} }
static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb) static void ip_cmsg_recv_retopts(struct net *net, struct msghdr *msg,
struct sk_buff *skb)
{ {
unsigned char optbuf[sizeof(struct ip_options) + 40]; unsigned char optbuf[sizeof(struct ip_options) + 40];
struct ip_options *opt = (struct ip_options *)optbuf; struct ip_options *opt = (struct ip_options *)optbuf;
...@@ -88,7 +89,7 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb) ...@@ -88,7 +89,7 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)
if (IPCB(skb)->opt.optlen == 0) if (IPCB(skb)->opt.optlen == 0)
return; return;
if (ip_options_echo(opt, skb)) { if (ip_options_echo(net, opt, skb)) {
msg->msg_flags |= MSG_CTRUNC; msg->msg_flags |= MSG_CTRUNC;
return; return;
} }
...@@ -204,7 +205,7 @@ void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, ...@@ -204,7 +205,7 @@ void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk,
} }
if (flags & IP_CMSG_RETOPTS) { if (flags & IP_CMSG_RETOPTS) {
ip_cmsg_recv_retopts(msg, skb); ip_cmsg_recv_retopts(sock_net(sk), msg, skb);
flags &= ~IP_CMSG_RETOPTS; flags &= ~IP_CMSG_RETOPTS;
if (!flags) if (!flags)
......
...@@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) ...@@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
/* We throwed the options of the initial SYN away, so we hope /* We throwed the options of the initial SYN away, so we hope
* the ACK carries the same options again (see RFC1122 4.2.3.8) * the ACK carries the same options again (see RFC1122 4.2.3.8)
*/ */
ireq->opt = tcp_v4_save_options(skb); ireq->opt = tcp_v4_save_options(sock_net(sk), skb);
if (security_inet_conn_request(sk, skb, req)) { if (security_inet_conn_request(sk, skb, req)) {
reqsk_free(req); reqsk_free(req);
......
...@@ -1267,7 +1267,7 @@ static void tcp_v4_init_req(struct request_sock *req, ...@@ -1267,7 +1267,7 @@ static void tcp_v4_init_req(struct request_sock *req,
sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);
sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr);
ireq->opt = tcp_v4_save_options(skb); ireq->opt = tcp_v4_save_options(sock_net(sk_listener), skb);
} }
static struct dst_entry *tcp_v4_route_req(const struct sock *sk, static struct dst_entry *tcp_v4_route_req(const struct sock *sk,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment