From patchwork Tue Jun 1 16:20:34 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Ebalard X-Patchwork-Id: 54263 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 12F96B7D2D for ; Wed, 2 Jun 2010 02:20:58 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756167Ab0FAQUu (ORCPT ); Tue, 1 Jun 2010 12:20:50 -0400 Received: from copper.chdir.org ([88.191.97.87]:60572 "EHLO copper.chdir.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756012Ab0FAQUt (ORCPT ); Tue, 1 Jun 2010 12:20:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=natisbad.org; s=mail; h=From:To:Cc:Subject:Date:Message-ID: MIME-Version:Content-Type; bh=df8UA4JDhzuhcdAlol9+VtUlYSG8QV/TFl fGv/z4VcY=; b=dr011vEoAfhWJ/1fFZ6JDXYrfsAqSTwGscUnjpbSmbyw1S/R3g uL8bEAaHR1VVah1YrCp0r+7heCPYK911ksd4gzioR6uRueZoY+gWHe/8y3ptpj7n aTY6s1DpTxc8mZ3ez3DSm8cj/co8hUAWW/7TkM6Xg0TgK6eEyLXne/MKk= Received: from [2001:7a8:78df:2:20d:93ff:fe55:8f79] (helo=small.ssi.corp) by copper.chdir.org with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.69) (envelope-from ) id 1OJUCs-0002CU-6Z; Tue, 01 Jun 2010 18:20:46 +0200 X-Hashcash: 1:20:100601:davem@davemloft.net::sDYYhprYxWkHcLal:0000000000000000000000000000000000000000005++8 X-Hashcash: 1:20:100601:yoshfuji@linux-ipv6.org::BB3LFL46T9ITfVF3:000000000000000000000000000000000000008Ilw X-Hashcash: 1:20:100601:netdev@vger.kernel.org::6wTL4y3kdft9272e:0000000000000000000000000000000000000008TzM From: arno@natisbad.org (Arnaud Ebalard) To: "David S. Miller" Cc: YOSHIFUJI Hideaki / =?utf-8?B?5ZCJ6Jek6Iux5piO?= , Subject: [PATCH] Refactor update of IPv6 flow destination address for srcrt (RH) option X-PGP-Key-URL: http://natisbad.org/arno@natisbad.org.asc X-Fingerprint: D3A5 B68A 839B 38A5 815A 781B B77C 0748 A7AE 341B Date: Tue, 01 Jun 2010 18:20:34 +0200 Message-ID: <87wruid8rx.fsf@small.ssi.corp> User-Agent: Gnus/5.110009 (No Gnus v0.9) Emacs/23.1.50 (gnu/linux) MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Hi, While playing with associated code, I noticed there are more than a dozen occurrences of the following in the IPv6 stack: if (opt && opt->srcrt) { struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; ipv6_addr_copy(&final, &fl.fl6_dst); ipv6_addr_copy(&fl.fl6_dst, rt0->addr); final_p = &final; } Maybe this can be replaced with a helper (not sure about the name though). Signed-off-by: Arnaud Ebalard --- include/net/ipv6.h | 13 +++++++++++++ net/dccp/ipv6.c | 24 +++--------------------- net/ipv6/af_inet6.c | 7 +------ net/ipv6/datagram.c | 16 +++------------- net/ipv6/inet6_connection_sock.c | 7 +------ net/ipv6/raw.c | 8 +------- net/ipv6/syncookies.c | 7 +------ net/ipv6/tcp_ipv6.c | 21 +++------------------ net/ipv6/udp.c | 9 ++------- 9 files changed, 28 insertions(+), 84 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 2600b69..9edfa1c 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -290,6 +290,19 @@ static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2 memcpy(a1, a2, sizeof(struct in6_addr)); } +static inline struct in6_addr *srcrt_dst_flow_update(struct in6_addr *final, + struct in6_addr *fl6dst, + const struct ipv6_txoptions *opt) +{ + if (opt && opt->srcrt) { + const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt; + ipv6_addr_copy(final, fl6dst); + ipv6_addr_copy(fl6dst, rt0->addr); + return final; + } + return NULL; +} + static inline void ipv6_addr_prefix(struct in6_addr *pfx, const struct in6_addr *addr, int plen) diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 0916988..fc435ba 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -265,13 +265,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, opt = np->opt; - if (opt != NULL && opt->srcrt != NULL) { - const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt; - - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, opt); err = ip6_dst_lookup(sk, &dst, &fl); if (err) @@ -551,13 +545,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, memset(&fl, 0, sizeof(fl)); fl.proto = IPPROTO_DCCP; ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); - if (opt != NULL && opt->srcrt != NULL) { - const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt; - - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, opt); ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); fl.oif = sk->sk_bound_dev_if; fl.fl_ip_dport = inet_rsk(req)->rmt_port; @@ -988,13 +976,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, fl.fl_ip_sport = inet->inet_sport; security_sk_classify_flow(sk, &fl); - if (np->opt != NULL && np->opt->srcrt != NULL) { - const struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; - - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, np->opt); err = ip6_dst_lookup(sk, &dst, &fl); if (err) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index e733942..d6e6491 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -665,12 +665,7 @@ int inet6_sk_rebuild_header(struct sock *sk) fl.fl_ip_sport = inet->inet_sport; security_sk_classify_flow(sk, &fl); - if (np->opt && np->opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, np->opt); err = ip6_dst_lookup(sk, &dst, &fl); if (err) { diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 7126846..2fcba06 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -42,6 +42,7 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) struct dst_entry *dst; struct flowi fl; struct ip6_flowlabel *flowlabel = NULL; + struct ipv6_txoptions *opt; int addr_type; int err; @@ -155,19 +156,8 @@ ipv4_connected: security_sk_classify_flow(sk, &fl); - if (flowlabel) { - if (flowlabel->opt && flowlabel->opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt; - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } - } else if (np->opt && np->opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + opt = flowlabel ? flowlabel->opt : np->opt; + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, opt); err = ip6_dst_lookup(sk, &dst, &fl); if (err) diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 0c5e3c3..505c8de 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -199,12 +199,7 @@ int inet6_csk_xmit(struct sk_buff *skb) fl.fl_ip_dport = inet->inet_dport; security_sk_classify_flow(sk, &fl); - if (np->opt && np->opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, np->opt); dst = __inet6_csk_dst_check(sk, np->dst_cookie); diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 4a4dcbe..91211bd 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -847,13 +847,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) ipv6_addr_copy(&fl.fl6_src, &np->saddr); - /* merge ip6_build_xmit from ip6_output */ - if (opt && opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, opt); if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) fl.oif = np->mcast_oif; diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 34d1f06..7d27bc7 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -245,12 +245,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) memset(&fl, 0, sizeof(fl)); fl.proto = IPPROTO_TCP; ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); - if (np->opt && np->opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, np->opt); ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); fl.oif = sk->sk_bound_dev_if; fl.mark = sk->sk_mark; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 2b7c3a1..2dcb536 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -250,12 +250,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, fl.fl_ip_dport = usin->sin6_port; fl.fl_ip_sport = inet->inet_sport; - if (np->opt && np->opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, np->opt); security_sk_classify_flow(sk, &fl); @@ -494,12 +489,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, security_req_classify_flow(req, &fl); opt = np->opt; - if (opt && opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, opt); err = ip6_dst_lookup(sk, &dst, &fl); if (err) @@ -1398,12 +1388,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, memset(&fl, 0, sizeof(fl)); fl.proto = IPPROTO_TCP; ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); - if (opt && opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; - } + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, opt); ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); fl.oif = sk->sk_bound_dev_if; fl.mark = sk->sk_mark; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 87be586..a46ad07 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1097,14 +1097,9 @@ do_udp_sendmsg: ipv6_addr_copy(&fl.fl6_src, &np->saddr); fl.fl_ip_sport = inet->inet_sport; - /* merge ip6_build_xmit from ip6_output */ - if (opt && opt->srcrt) { - struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; - ipv6_addr_copy(&final, &fl.fl6_dst); - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); - final_p = &final; + final_p = srcrt_dst_flow_update(&final, &fl.fl6_dst, opt); + if (final_p) connected = 0; - } if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) { fl.oif = np->mcast_oif;