Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21e27f2d authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'IP-cleanup-LSRR-option-processing'

Paolo Abeni says:

====================
IP: cleanup LSRR option processing

The __ip_options_echo() function expect a valid dst entry in skb->dst;
as result we sometimes need to preserve the dst entry for the whole IP
RX path.

The current usage of skb->dst looks more a relic from ancient past that
a real functional constraint. This patchset tries to remove such usage,
and than drops some hacks currently in place in the IP code to keep
skb->dst around.

__ip_options_echo() uses of skb->dst for two different purposes: retrieving
the netns assicated with the skb, and modify the ingress packet LSRR address
list.

The first patch removes the code modifying the ingress packet, and the second
one provides an explicit netns argument to __ip_options_echo(). The following
patches cleanup the current code keeping arund skb->dst for __ip_options_echo's
sake.

Updating the __ip_options_echo() function has been previously discussed here:

http://marc.info/?l=linux-netdev&m=150064533516348&w=2


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a54df682 3bdefdf9
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -567,11 +567,12 @@ int ip_forward(struct sk_buff *skb);
void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
		      __be32 daddr, struct rtable *rt, int is_frag);

int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb,
		      const struct ip_options *sopt);
static inline int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb)
int __ip_options_echo(struct net *net, struct ip_options *dopt,
		      struct sk_buff *skb, const struct ip_options *sopt);
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);
+3 −2
Original line number Diff line number Diff line
@@ -1885,7 +1885,8 @@ extern void tcp_rack_reo_timeout(struct sock *sk);
/*
 * 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;
	struct ip_options_rcu *dopt = NULL;
@@ -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;

		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);
			dopt = NULL;
		}
+2 −2
Original line number Diff line number Diff line
@@ -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 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;

	/* 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)
					  iph->tos;
	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;


+3 −6
Original line number Diff line number Diff line
@@ -86,8 +86,8 @@ void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
 * NOTE: dopt cannot point to skb.
 */

int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb,
		      const struct ip_options *sopt)
int __ip_options_echo(struct net *net, struct ip_options *dopt,
		      struct sk_buff *skb, const struct ip_options *sopt)
{
	unsigned char *sptr, *dptr;
	int soffset, doffset;
@@ -140,7 +140,7 @@ int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb,
						__be32 addr;

						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;
							soffset += 8;
						}
@@ -174,9 +174,6 @@ int __ip_options_echo(struct ip_options *dopt, struct sk_buff *skb,
				doffset -= 4;
		}
		if (doffset > 3) {
			__be32 daddr = fib_compute_spec_dst(skb);

			memcpy(&start[doffset-1], &daddr, 4);
			dopt->faddr = faddr;
			dptr[0] = start[0];
			dptr[1] = doffset+3;
+1 −1
Original line number Diff line number Diff line
@@ -1525,7 +1525,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
	int err;
	int oif;

	if (__ip_options_echo(&replyopts.opt.opt, skb, sopt))
	if (__ip_options_echo(net, &replyopts.opt.opt, skb, sopt))
		return;

	ipc.addr = daddr;
Loading