* [PATCH 20/25] net: Use flowi4 and flowi6 in xfrm layer.
From: David Miller @ 2011-03-12 23:29 UTC (permalink / raw)
To: netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/xfrm.h | 24 ++++++++++++------------
net/ipv4/xfrm4_policy.c | 46 ++++++++++++++++++++++++----------------------
net/ipv4/xfrm4_state.c | 14 ++++++++------
net/ipv6/xfrm6_policy.c | 39 +++++++++++++++++++++------------------
net/ipv6/xfrm6_state.c | 14 ++++++++------
net/xfrm/xfrm_policy.c | 28 ++++++++++++++++------------
6 files changed, 89 insertions(+), 76 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index aa860ad..8f8bd82 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1142,9 +1142,9 @@ xfrm_address_t *xfrm_flowi_daddr(const struct flowi *fl, unsigned short family)
{
switch (family){
case AF_INET:
- return (xfrm_address_t *)&fl->fl4_dst;
+ return (xfrm_address_t *)&fl->u.ip4.daddr;
case AF_INET6:
- return (xfrm_address_t *)&fl->fl6_dst;
+ return (xfrm_address_t *)&fl->u.ip6.daddr;
}
return NULL;
}
@@ -1154,9 +1154,9 @@ xfrm_address_t *xfrm_flowi_saddr(const struct flowi *fl, unsigned short family)
{
switch (family){
case AF_INET:
- return (xfrm_address_t *)&fl->fl4_src;
+ return (xfrm_address_t *)&fl->u.ip4.saddr;
case AF_INET6:
- return (xfrm_address_t *)&fl->fl6_src;
+ return (xfrm_address_t *)&fl->u.ip6.saddr;
}
return NULL;
}
@@ -1168,12 +1168,12 @@ void xfrm_flowi_addr_get(const struct flowi *fl,
{
switch(family) {
case AF_INET:
- memcpy(&saddr->a4, &fl->fl4_src, sizeof(saddr->a4));
- memcpy(&daddr->a4, &fl->fl4_dst, sizeof(daddr->a4));
+ memcpy(&saddr->a4, &fl->u.ip4.saddr, sizeof(saddr->a4));
+ memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4));
break;
case AF_INET6:
- ipv6_addr_copy((struct in6_addr *)&saddr->a6, &fl->fl6_src);
- ipv6_addr_copy((struct in6_addr *)&daddr->a6, &fl->fl6_dst);
+ ipv6_addr_copy((struct in6_addr *)&saddr->a6, &fl->u.ip6.saddr);
+ ipv6_addr_copy((struct in6_addr *)&daddr->a6, &fl->u.ip6.daddr);
break;
}
}
@@ -1221,12 +1221,12 @@ xfrm_state_addr_flow_check(const struct xfrm_state *x, const struct flowi *fl,
switch (family) {
case AF_INET:
return __xfrm4_state_addr_check(x,
- (const xfrm_address_t *)&fl->fl4_dst,
- (const xfrm_address_t *)&fl->fl4_src);
+ (const xfrm_address_t *)&fl->u.ip4.daddr,
+ (const xfrm_address_t *)&fl->u.ip4.saddr);
case AF_INET6:
return __xfrm6_state_addr_check(x,
- (const xfrm_address_t *)&fl->fl6_dst,
- (const xfrm_address_t *)&fl->fl6_src);
+ (const xfrm_address_t *)&fl->u.ip6.daddr,
+ (const xfrm_address_t *)&fl->u.ip6.saddr);
}
return 0;
}
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index b111f468..30b312c 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -56,7 +56,7 @@ static int xfrm4_get_saddr(struct net *net,
static int xfrm4_get_tos(const struct flowi *fl)
{
- return IPTOS_RT_MASK & fl->fl4_tos; /* Strip ECN bits */
+ return IPTOS_RT_MASK & fl->u.ip4.flowi4_tos; /* Strip ECN bits */
}
static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
@@ -69,13 +69,14 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
const struct flowi *fl)
{
struct rtable *rt = (struct rtable *)xdst->route;
+ const struct flowi4 *fl4 = &fl->u.ip4;
- rt->rt_key_dst = fl->fl4_dst;
- rt->rt_key_src = fl->fl4_src;
- rt->rt_tos = fl->fl4_tos;
- rt->rt_iif = fl->flowi_iif;
- rt->rt_oif = fl->flowi_oif;
- rt->rt_mark = fl->flowi_mark;
+ rt->rt_key_dst = fl4->daddr;
+ rt->rt_key_src = fl4->saddr;
+ rt->rt_tos = fl4->flowi4_tos;
+ rt->rt_iif = fl4->flowi4_iif;
+ rt->rt_oif = fl4->flowi4_oif;
+ rt->rt_mark = fl4->flowi4_mark;
xdst->u.dst.dev = dev;
dev_hold(dev);
@@ -102,9 +103,10 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
{
struct iphdr *iph = ip_hdr(skb);
u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
+ struct flowi4 *fl4 = &fl->u.ip4;
- memset(fl, 0, sizeof(struct flowi));
- fl->flowi_mark = skb->mark;
+ memset(fl4, 0, sizeof(struct flowi4));
+ fl4->flowi4_mark = skb->mark;
if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) {
switch (iph->protocol) {
@@ -117,8 +119,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be16 *ports = (__be16 *)xprth;
- fl->fl4_sport = ports[!!reverse];
- fl->fl4_dport = ports[!reverse];
+ fl4->uli.ports.sport = ports[!!reverse];
+ fl4->uli.ports.dport = ports[!reverse];
}
break;
@@ -126,8 +128,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
if (pskb_may_pull(skb, xprth + 2 - skb->data)) {
u8 *icmp = xprth;
- fl->fl4_icmp_type = icmp[0];
- fl->fl4_icmp_code = icmp[1];
+ fl4->uli.icmpt.type = icmp[0];
+ fl4->uli.icmpt.code = icmp[1];
}
break;
@@ -135,7 +137,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be32 *ehdr = (__be32 *)xprth;
- fl->fl4_ipsec_spi = ehdr[0];
+ fl4->uli.spi = ehdr[0];
}
break;
@@ -143,7 +145,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
if (pskb_may_pull(skb, xprth + 8 - skb->data)) {
__be32 *ah_hdr = (__be32*)xprth;
- fl->fl4_ipsec_spi = ah_hdr[1];
+ fl4->uli.spi = ah_hdr[1];
}
break;
@@ -151,7 +153,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be16 *ipcomp_hdr = (__be16 *)xprth;
- fl->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
+ fl4->uli.spi = htonl(ntohs(ipcomp_hdr[1]));
}
break;
@@ -163,20 +165,20 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
if (greflags[0] & GRE_KEY) {
if (greflags[0] & GRE_CSUM)
gre_hdr++;
- fl->fl4_gre_key = gre_hdr[1];
+ fl4->uli.gre_key = gre_hdr[1];
}
}
break;
default:
- fl->fl4_ipsec_spi = 0;
+ fl4->uli.spi = 0;
break;
}
}
- fl->flowi_proto = iph->protocol;
- fl->fl4_dst = reverse ? iph->saddr : iph->daddr;
- fl->fl4_src = reverse ? iph->daddr : iph->saddr;
- fl->fl4_tos = iph->tos;
+ fl4->flowi4_proto = iph->protocol;
+ fl4->daddr = reverse ? iph->saddr : iph->daddr;
+ fl4->saddr = reverse ? iph->daddr : iph->saddr;
+ fl4->flowi4_tos = iph->tos;
}
static inline int xfrm4_garbage_collect(struct dst_ops *ops)
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index d8d5419..1717c64 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -23,17 +23,19 @@ static int xfrm4_init_flags(struct xfrm_state *x)
static void
__xfrm4_init_tempsel(struct xfrm_selector *sel, const struct flowi *fl)
{
- sel->daddr.a4 = fl->fl4_dst;
- sel->saddr.a4 = fl->fl4_src;
- sel->dport = xfrm_flowi_dport(fl, &fl->u.ip4.uli);
+ const struct flowi4 *fl4 = &fl->u.ip4;
+
+ sel->daddr.a4 = fl4->daddr;
+ sel->saddr.a4 = fl4->saddr;
+ sel->dport = xfrm_flowi_dport(fl, &fl4->uli);
sel->dport_mask = htons(0xffff);
- sel->sport = xfrm_flowi_sport(fl, &fl->u.ip4.uli);
+ sel->sport = xfrm_flowi_sport(fl, &fl4->uli);
sel->sport_mask = htons(0xffff);
sel->family = AF_INET;
sel->prefixlen_d = 32;
sel->prefixlen_s = 32;
- sel->proto = fl->flowi_proto;
- sel->ifindex = fl->flowi_oif;
+ sel->proto = fl4->flowi4_proto;
+ sel->ifindex = fl4->flowi4_oif;
}
static void
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 213c759..254aa6d 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -30,15 +30,17 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos,
const xfrm_address_t *saddr,
const xfrm_address_t *daddr)
{
- struct flowi fl = {};
+ struct flowi6 fl6;
struct dst_entry *dst;
int err;
- memcpy(&fl.fl6_dst, daddr, sizeof(fl.fl6_dst));
+ memset(&fl6, 0, sizeof(fl6));
+ memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr));
if (saddr)
- memcpy(&fl.fl6_src, saddr, sizeof(fl.fl6_src));
+ memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr));
- dst = ip6_route_output(net, NULL, &fl);
+ dst = ip6_route_output(net, NULL,
+ flowi6_to_flowi(&fl6));
err = dst->error;
if (dst->error) {
@@ -120,6 +122,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
static inline void
_decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
{
+ struct flowi6 *fl6 = &fl->u.ip6;
int onlyproto = 0;
u16 offset = skb_network_header_len(skb);
struct ipv6hdr *hdr = ipv6_hdr(skb);
@@ -127,11 +130,11 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
const unsigned char *nh = skb_network_header(skb);
u8 nexthdr = nh[IP6CB(skb)->nhoff];
- memset(fl, 0, sizeof(struct flowi));
- fl->flowi_mark = skb->mark;
+ memset(fl6, 0, sizeof(struct flowi6));
+ fl6->flowi6_mark = skb->mark;
- ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr);
- ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr);
+ ipv6_addr_copy(&fl6->daddr, reverse ? &hdr->saddr : &hdr->daddr);
+ ipv6_addr_copy(&fl6->saddr, reverse ? &hdr->daddr : &hdr->saddr);
while (nh + offset + 1 < skb->data ||
pskb_may_pull(skb, nh + offset + 1 - skb->data)) {
@@ -158,20 +161,20 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
pskb_may_pull(skb, nh + offset + 4 - skb->data))) {
__be16 *ports = (__be16 *)exthdr;
- fl->fl6_sport = ports[!!reverse];
- fl->fl6_dport = ports[!reverse];
+ fl6->uli.ports.sport = ports[!!reverse];
+ fl6->uli.ports.dport = ports[!reverse];
}
- fl->flowi_proto = nexthdr;
+ fl6->flowi6_proto = nexthdr;
return;
case IPPROTO_ICMPV6:
if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
u8 *icmp = (u8 *)exthdr;
- fl->fl6_icmp_type = icmp[0];
- fl->fl6_icmp_code = icmp[1];
+ fl6->uli.icmpt.type = icmp[0];
+ fl6->uli.icmpt.code = icmp[1];
}
- fl->flowi_proto = nexthdr;
+ fl6->flowi6_proto = nexthdr;
return;
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
@@ -180,9 +183,9 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
struct ip6_mh *mh;
mh = (struct ip6_mh *)exthdr;
- fl->fl6_mh_type = mh->ip6mh_type;
+ fl6->uli.mht.type = mh->ip6mh_type;
}
- fl->flowi_proto = nexthdr;
+ fl6->flowi6_proto = nexthdr;
return;
#endif
@@ -191,8 +194,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
case IPPROTO_ESP:
case IPPROTO_COMP:
default:
- fl->fl6_ipsec_spi = 0;
- fl->flowi_proto = nexthdr;
+ fl6->uli.spi = 0;
+ fl6->flowi6_proto = nexthdr;
return;
}
}
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index b456533..afe941e 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -22,19 +22,21 @@
static void
__xfrm6_init_tempsel(struct xfrm_selector *sel, const struct flowi *fl)
{
+ const struct flowi6 *fl6 = &fl->u.ip6;
+
/* Initialize temporary selector matching only
* to current session. */
- ipv6_addr_copy((struct in6_addr *)&sel->daddr, &fl->fl6_dst);
- ipv6_addr_copy((struct in6_addr *)&sel->saddr, &fl->fl6_src);
- sel->dport = xfrm_flowi_dport(fl, &fl->u.ip6.uli);
+ ipv6_addr_copy((struct in6_addr *)&sel->daddr, &fl6->daddr);
+ ipv6_addr_copy((struct in6_addr *)&sel->saddr, &fl6->saddr);
+ sel->dport = xfrm_flowi_dport(fl, &fl6->uli);
sel->dport_mask = htons(0xffff);
- sel->sport = xfrm_flowi_sport(fl, &fl->u.ip6.uli);
+ sel->sport = xfrm_flowi_sport(fl, &fl6->uli);
sel->sport_mask = htons(0xffff);
sel->family = AF_INET6;
sel->prefixlen_d = 128;
sel->prefixlen_s = 128;
- sel->proto = fl->flowi_proto;
- sel->ifindex = fl->flowi_oif;
+ sel->proto = fl6->flowi6_proto;
+ sel->ifindex = fl6->flowi6_oif;
}
static void
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 2ecd18a..1ba0258 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -59,23 +59,27 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
static inline int
__xfrm4_selector_match(const struct xfrm_selector *sel, const struct flowi *fl)
{
- return addr_match(&fl->fl4_dst, &sel->daddr, sel->prefixlen_d) &&
- addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) &&
- !((xfrm_flowi_dport(fl, &fl->u.ip4.uli) ^ sel->dport) & sel->dport_mask) &&
- !((xfrm_flowi_sport(fl, &fl->u.ip4.uli) ^ sel->sport) & sel->sport_mask) &&
- (fl->flowi_proto == sel->proto || !sel->proto) &&
- (fl->flowi_oif == sel->ifindex || !sel->ifindex);
+ const struct flowi4 *fl4 = &fl->u.ip4;
+
+ return addr_match(&fl4->daddr, &sel->daddr, sel->prefixlen_d) &&
+ addr_match(&fl4->saddr, &sel->saddr, sel->prefixlen_s) &&
+ !((xfrm_flowi_dport(fl, &fl4->uli) ^ sel->dport) & sel->dport_mask) &&
+ !((xfrm_flowi_sport(fl, &fl4->uli) ^ sel->sport) & sel->sport_mask) &&
+ (fl4->flowi4_proto == sel->proto || !sel->proto) &&
+ (fl4->flowi4_oif == sel->ifindex || !sel->ifindex);
}
static inline int
__xfrm6_selector_match(const struct xfrm_selector *sel, const struct flowi *fl)
{
- return addr_match(&fl->fl6_dst, &sel->daddr, sel->prefixlen_d) &&
- addr_match(&fl->fl6_src, &sel->saddr, sel->prefixlen_s) &&
- !((xfrm_flowi_dport(fl, &fl->u.ip6.uli) ^ sel->dport) & sel->dport_mask) &&
- !((xfrm_flowi_sport(fl, &fl->u.ip6.uli) ^ sel->sport) & sel->sport_mask) &&
- (fl->flowi_proto == sel->proto || !sel->proto) &&
- (fl->flowi_oif == sel->ifindex || !sel->ifindex);
+ const struct flowi6 *fl6 = &fl->u.ip6;
+
+ return addr_match(&fl6->daddr, &sel->daddr, sel->prefixlen_d) &&
+ addr_match(&fl6->saddr, &sel->saddr, sel->prefixlen_s) &&
+ !((xfrm_flowi_dport(fl, &fl6->uli) ^ sel->dport) & sel->dport_mask) &&
+ !((xfrm_flowi_sport(fl, &fl6->uli) ^ sel->sport) & sel->sport_mask) &&
+ (fl6->flowi6_proto == sel->proto || !sel->proto) &&
+ (fl6->flowi6_oif == sel->ifindex || !sel->ifindex);
}
int xfrm_selector_match(const struct xfrm_selector *sel, const struct flowi *fl,
--
1.7.4.1
^ permalink raw reply related
* [PATCH 21/25] ipv4: Kill fib_semantic_match declaration from fib_lookup.h
From: David Miller @ 2011-03-12 23:30 UTC (permalink / raw)
To: netdev
This function no longer exists.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv4/fib_lookup.h | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index 84db2da..4ec3238 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -25,9 +25,6 @@ static inline void fib_alias_accessed(struct fib_alias *fa)
}
/* Exported by fib_semantics.c */
-extern int fib_semantic_match(struct fib_table *tb, struct list_head *head,
- const struct flowi *flp,
- struct fib_result *res, int prefixlen, int fib_flags);
extern void fib_release_info(struct fib_info *);
extern struct fib_info *fib_create_info(struct fib_config *cfg);
extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 22/25] net: Put fl4_* macros to struct flowi4 and use them again.
From: David Miller @ 2011-03-12 23:30 UTC (permalink / raw)
To: netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/flow.h | 18 +++++++-----------
include/net/route.h | 14 +++++++-------
net/dccp/ipv4.c | 4 ++--
net/ipv4/icmp.c | 4 ++--
net/ipv4/inet_connection_sock.c | 4 ++--
net/ipv4/ip_output.c | 4 ++--
net/ipv4/netfilter/nf_nat_standalone.c | 4 ++--
net/ipv4/raw.c | 4 ++--
net/ipv4/syncookies.c | 4 ++--
net/ipv4/udp.c | 10 +++++-----
net/ipv4/xfrm4_policy.c | 18 +++++++++---------
net/sctp/protocol.c | 8 ++++----
12 files changed, 46 insertions(+), 50 deletions(-)
diff --git a/include/net/flow.h b/include/net/flow.h
index 8d5b402..44bd376 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -61,6 +61,13 @@ struct flowi4 {
__be32 daddr;
__be32 saddr;
union flowi_uli uli;
+#define fl4_sport uli.ports.sport
+#define fl4_dport uli.ports.dport
+#define fl4_icmp_type uli.icmpt.type
+#define fl4_icmp_code uli.icmpt.code
+#define fl4_ipsec_spi uli.spi
+#define fl4_mh_type uli.mht.type
+#define fl4_gre_key uli.gre_key
};
struct flowi6 {
@@ -101,8 +108,6 @@ struct flowi {
#define flowi_proto u.__fl_common.flowic_proto
#define flowi_flags u.__fl_common.flowic_flags
#define flowi_secid u.__fl_common.flowic_secid
-#define fl4_tos flowi_tos
-#define fl4_scope flowi_scope
#define fld_scope flowi_scope
#define fld_dst u.dn.daddr
@@ -110,15 +115,6 @@ struct flowi {
#define fl6_dst u.ip6.daddr
#define fl6_src u.ip6.saddr
#define fl6_flowlabel u.ip6.flowlabel
-#define fl4_dst u.ip4.daddr
-#define fl4_src u.ip4.saddr
-#define fl4_sport u.ip4.uli.ports.sport
-#define fl4_dport u.ip4.uli.ports.dport
-#define fl4_icmp_type u.ip4.uli.icmpt.type
-#define fl4_icmp_code u.ip4.uli.icmpt.code
-#define fl4_ipsec_spi u.ip4.uli.spi
-#define fl4_mh_type u.ip4.uli.mht.type
-#define fl4_gre_key u.ip4.uli.gre_key
#define fl6_sport u.ip6.uli.ports.sport
#define fl6_dport u.ip6.uli.ports.dport
#define fl6_icmp_type u.ip6.uli.icmpt.type
diff --git a/include/net/route.h b/include/net/route.h
index 80b0353..30d6cae 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -157,8 +157,8 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock
.saddr = saddr,
.flowi4_tos = tos,
.flowi4_proto = proto,
- .uli.ports.dport = dport,
- .uli.ports.sport = sport,
+ .fl4_dport = dport,
+ .fl4_sport = sport,
};
if (sk)
security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
@@ -175,7 +175,7 @@ static inline struct rtable *ip_route_output_gre(struct net *net,
.saddr = saddr,
.flowi4_tos = tos,
.flowi4_proto = IPPROTO_GRE,
- .uli.gre_key = gre_key,
+ .fl4_gre_key = gre_key,
};
return ip_route_output_key(net, &fl4);
}
@@ -235,8 +235,8 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos,
.saddr = src,
.flowi4_tos = tos,
.flowi4_proto = protocol,
- .uli.ports.sport = sport,
- .uli.ports.dport = dport,
+ .fl4_sport = sport,
+ .fl4_dport = dport,
};
struct net *net = sock_net(sk);
struct rtable *rt;
@@ -273,8 +273,8 @@ static inline struct rtable *ip_route_newports(struct rtable *rt,
.saddr = rt->rt_key_src,
.flowi4_tos = rt->rt_tos,
.flowi4_proto = protocol,
- .uli.ports.sport = sport,
- .uli.ports.dport = dport
+ .fl4_sport = sport,
+ .fl4_dport = dport
};
if (inet_sk(sk)->transparent)
fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index be98470..ae451c6 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -471,8 +471,8 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
.saddr = ip_hdr(skb)->daddr,
.flowi4_tos = RT_CONN_FLAGS(sk),
.flowi4_proto = sk->sk_protocol,
- .uli.ports.sport = dccp_hdr(skb)->dccph_dport,
- .uli.ports.dport = dccp_hdr(skb)->dccph_sport,
+ .fl4_sport = dccp_hdr(skb)->dccph_dport,
+ .fl4_dport = dccp_hdr(skb)->dccph_sport,
};
security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 8eca3c2..a91dc16 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -384,8 +384,8 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
.saddr = saddr,
.flowi4_tos = RT_TOS(tos),
.flowi4_proto = IPPROTO_ICMP,
- .uli.icmpt.type = type,
- .uli.icmpt.code = code,
+ .fl4_icmp_type = type,
+ .fl4_icmp_code = code,
};
struct rtable *rt, *rt2;
int err;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index beecc12..6c0b7f4 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -365,8 +365,8 @@ struct dst_entry *inet_csk_route_req(struct sock *sk,
.flowi4_tos = RT_CONN_FLAGS(sk),
.flowi4_proto = sk->sk_protocol,
.flowi4_flags = inet_sk_flowi_flags(sk),
- .uli.ports.sport = inet_sk(sk)->inet_sport,
- .uli.ports.dport = ireq->rmt_port,
+ .fl4_sport = inet_sk(sk)->inet_sport,
+ .fl4_dport = ireq->rmt_port,
};
struct net *net = sock_net(sk);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 2b9cc40..67f241b 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1479,8 +1479,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
.daddr = daddr,
.saddr = rt->rt_spec_dst,
.flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
- .uli.ports.sport = tcp_hdr(skb)->dest,
- .uli.ports.dport = tcp_hdr(skb)->source,
+ .fl4_sport = tcp_hdr(skb)->dest,
+ .fl4_dport = tcp_hdr(skb)->source,
.flowi4_proto = sk->sk_protocol,
.flowi4_flags = ip_reply_arg_flowi_flags(arg),
};
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 963320b..7317bdf 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -56,7 +56,7 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
t->dst.protonum == IPPROTO_UDPLITE ||
t->dst.protonum == IPPROTO_DCCP ||
t->dst.protonum == IPPROTO_SCTP)
- fl4->uli.ports.dport = t->dst.u.tcp.port;
+ fl4->fl4_dport = t->dst.u.tcp.port;
}
statusbit ^= IPS_NAT_MASK;
@@ -68,7 +68,7 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
t->dst.protonum == IPPROTO_UDPLITE ||
t->dst.protonum == IPPROTO_DCCP ||
t->dst.protonum == IPPROTO_SCTP)
- fl4->uli.ports.sport = t->src.u.tcp.port;
+ fl4->fl4_sport = t->src.u.tcp.port;
}
}
#endif
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 452e178..e837ffd 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -433,8 +433,8 @@ static int raw_probe_proto_opt(struct flowi4 *fl4, struct msghdr *msg)
code = iov->iov_base;
if (type && code) {
- if (get_user(fl4->uli.icmpt.type, type) ||
- get_user(fl4->uli.icmpt.code, code))
+ if (get_user(fl4->fl4_icmp_type, type) ||
+ get_user(fl4->fl4_icmp_code, code))
return -EFAULT;
probed = 1;
}
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index e3b5b75..8b44c6d 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -353,8 +353,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
.flowi4_tos = RT_CONN_FLAGS(sk),
.flowi4_proto = IPPROTO_TCP,
.flowi4_flags = inet_sk_flowi_flags(sk),
- .uli.ports.sport = th->dest,
- .uli.ports.dport = th->source,
+ .fl4_sport = th->dest,
+ .fl4_dport = th->source,
};
security_req_classify_flow(req, flowi4_to_flowi(&fl4));
rt = ip_route_output_key(sock_net(sk), &fl4);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 91cba3c..588f47a 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -778,7 +778,7 @@ static int udp_push_pending_frames(struct sock *sk)
if (!skb)
goto out;
- err = udp_send_skb(skb, fl4->daddr, fl4->uli.ports.dport);
+ err = udp_send_skb(skb, fl4->daddr, fl4->fl4_dport);
out:
up->len = 0;
@@ -918,8 +918,8 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
.flowi4_proto = sk->sk_protocol,
.flowi4_flags = (inet_sk_flowi_flags(sk) |
FLOWI_FLAG_CAN_SLEEP),
- .uli.ports.sport = inet->inet_sport,
- .uli.ports.dport = dport,
+ .fl4_sport = inet->inet_sport,
+ .fl4_dport = dport,
};
struct net *net = sock_net(sk);
@@ -976,8 +976,8 @@ back_from_confirm:
fl4 = &inet->cork.fl.u.ip4;
fl4->daddr = daddr;
fl4->saddr = saddr;
- fl4->uli.ports.dport = dport;
- fl4->uli.ports.sport = inet->inet_sport;
+ fl4->fl4_dport = dport;
+ fl4->fl4_sport = inet->inet_sport;
up->pending = AF_INET;
do_append_data:
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 30b312c..13e0e7f 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -119,8 +119,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be16 *ports = (__be16 *)xprth;
- fl4->uli.ports.sport = ports[!!reverse];
- fl4->uli.ports.dport = ports[!reverse];
+ fl4->fl4_sport = ports[!!reverse];
+ fl4->fl4_dport = ports[!reverse];
}
break;
@@ -128,8 +128,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
if (pskb_may_pull(skb, xprth + 2 - skb->data)) {
u8 *icmp = xprth;
- fl4->uli.icmpt.type = icmp[0];
- fl4->uli.icmpt.code = icmp[1];
+ fl4->fl4_icmp_type = icmp[0];
+ fl4->fl4_icmp_code = icmp[1];
}
break;
@@ -137,7 +137,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be32 *ehdr = (__be32 *)xprth;
- fl4->uli.spi = ehdr[0];
+ fl4->fl4_ipsec_spi = ehdr[0];
}
break;
@@ -145,7 +145,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
if (pskb_may_pull(skb, xprth + 8 - skb->data)) {
__be32 *ah_hdr = (__be32*)xprth;
- fl4->uli.spi = ah_hdr[1];
+ fl4->fl4_ipsec_spi = ah_hdr[1];
}
break;
@@ -153,7 +153,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be16 *ipcomp_hdr = (__be16 *)xprth;
- fl4->uli.spi = htonl(ntohs(ipcomp_hdr[1]));
+ fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
}
break;
@@ -165,13 +165,13 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
if (greflags[0] & GRE_KEY) {
if (greflags[0] & GRE_CSUM)
gre_hdr++;
- fl4->uli.gre_key = gre_hdr[1];
+ fl4->fl4_gre_key = gre_hdr[1];
}
}
break;
default:
- fl4->uli.spi = 0;
+ fl4->fl4_ipsec_spi = 0;
break;
}
}
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 31c0456..152976e 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -476,16 +476,16 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
memset(&fl4, 0x0, sizeof(struct flowi4));
fl4.daddr = daddr->v4.sin_addr.s_addr;
- fl4.uli.ports.dport = daddr->v4.sin_port;
+ fl4.fl4_dport = daddr->v4.sin_port;
fl4.flowi4_proto = IPPROTO_SCTP;
if (asoc) {
fl4.flowi4_tos = RT_CONN_FLAGS(asoc->base.sk);
fl4.flowi4_oif = asoc->base.sk->sk_bound_dev_if;
- fl4.uli.ports.sport = htons(asoc->base.bind_addr.port);
+ fl4.fl4_sport = htons(asoc->base.bind_addr.port);
}
if (saddr) {
fl4.saddr = saddr->v4.sin_addr.s_addr;
- fl4.uli.ports.sport = saddr->v4.sin_port;
+ fl4.fl4_sport = saddr->v4.sin_port;
}
SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ",
@@ -534,7 +534,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
if ((laddr->state == SCTP_ADDR_SRC) &&
(AF_INET == laddr->a.sa.sa_family)) {
fl4.saddr = laddr->a.v4.sin_addr.s_addr;
- fl4.uli.ports.sport = laddr->a.v4.sin_port;
+ fl4.fl4_sport = laddr->a.v4.sin_port;
rt = ip_route_output_key(&init_net, &fl4);
if (!IS_ERR(rt)) {
dst = &rt->dst;
--
1.7.4.1
^ permalink raw reply related
* [PATCH 23/25] ipv6: Convert to use flowi6 where applicable.
From: David Miller @ 2011-03-12 23:32 UTC (permalink / raw)
To: netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/infiniband/core/addr.c | 18 +++---
drivers/net/cnic.c | 12 ++--
include/linux/icmpv6.h | 4 +-
include/net/ip6_fib.h | 4 +-
include/net/ip6_route.h | 2 +-
include/net/ipv6.h | 16 ++--
include/net/transp_v6.h | 4 +-
net/dccp/ipv6.c | 132 +++++++++++++++++++-------------------
net/ipv6/af_inet6.c | 32 +++++-----
net/ipv6/datagram.c | 75 +++++++++++-----------
net/ipv6/exthdrs.c | 12 ++--
net/ipv6/fib6_rules.c | 19 +++--
net/ipv6/icmp.c | 110 ++++++++++++++++----------------
net/ipv6/inet6_connection_sock.c | 60 +++++++++---------
net/ipv6/ip6_fib.c | 4 +-
net/ipv6/ip6_flowlabel.c | 6 +-
net/ipv6/ip6_output.c | 90 +++++++++++++-------------
net/ipv6/ip6_tunnel.c | 50 +++++++-------
net/ipv6/ip6mr.c | 53 ++++++++--------
net/ipv6/ipv6_sockglue.c | 10 ++--
net/ipv6/mcast.c | 12 ++--
net/ipv6/mip6.c | 13 ++--
net/ipv6/ndisc.c | 14 ++--
net/ipv6/netfilter.c | 18 +++---
net/ipv6/netfilter/ip6t_REJECT.c | 20 +++---
net/ipv6/raw.c | 79 +++++++++++------------
net/ipv6/route.c | 96 ++++++++++++++--------------
net/ipv6/syncookies.c | 26 ++++----
net/ipv6/tcp_ipv6.c | 114 ++++++++++++++++----------------
net/ipv6/udp.c | 76 +++++++++++-----------
net/ipv6/xfrm6_policy.c | 3 +-
net/netfilter/ipvs/ip_vs_ctl.c | 10 +--
net/netfilter/ipvs/ip_vs_xmit.c | 14 ++--
net/netfilter/xt_TEE.c | 12 ++--
net/sctp/ipv6.c | 42 ++++++------
35 files changed, 632 insertions(+), 630 deletions(-)
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 3c2b309..e0ef5fd 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -231,28 +231,28 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
struct sockaddr_in6 *dst_in,
struct rdma_dev_addr *addr)
{
- struct flowi fl;
+ struct flowi6 fl6;
struct neighbour *neigh;
struct dst_entry *dst;
int ret;
- memset(&fl, 0, sizeof fl);
- ipv6_addr_copy(&fl.fl6_dst, &dst_in->sin6_addr);
- ipv6_addr_copy(&fl.fl6_src, &src_in->sin6_addr);
- fl.flowi_oif = addr->bound_dev_if;
+ memset(&fl6, 0, sizeof fl6);
+ ipv6_addr_copy(&fl6.daddr, &dst_in->sin6_addr);
+ ipv6_addr_copy(&fl6.saddr, &src_in->sin6_addr);
+ fl6.flowi6_oif = addr->bound_dev_if;
- dst = ip6_route_output(&init_net, NULL, &fl);
+ dst = ip6_route_output(&init_net, NULL, &fl6);
if ((ret = dst->error))
goto put;
- if (ipv6_addr_any(&fl.fl6_src)) {
+ if (ipv6_addr_any(&fl6.saddr)) {
ret = ipv6_dev_get_saddr(&init_net, ip6_dst_idev(dst)->dev,
- &fl.fl6_dst, 0, &fl.fl6_src);
+ &fl6.daddr, 0, &fl6.saddr);
if (ret)
goto put;
src_in->sin6_family = AF_INET6;
- ipv6_addr_copy(&src_in->sin6_addr, &fl.fl6_src);
+ ipv6_addr_copy(&src_in->sin6_addr, &fl6.saddr);
}
if (dst->dev->flags & IFF_LOOPBACK) {
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index c8922f6..8cca60e 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -3424,14 +3424,14 @@ static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr,
struct dst_entry **dst)
{
#if defined(CONFIG_IPV6) || (defined(CONFIG_IPV6_MODULE) && defined(MODULE))
- struct flowi fl;
+ struct flowi6 fl6;
- memset(&fl, 0, sizeof(fl));
- ipv6_addr_copy(&fl.fl6_dst, &dst_addr->sin6_addr);
- if (ipv6_addr_type(&fl.fl6_dst) & IPV6_ADDR_LINKLOCAL)
- fl.flowi_oif = dst_addr->sin6_scope_id;
+ memset(&fl6, 0, sizeof(fl6));
+ ipv6_addr_copy(&fl6.daddr, &dst_addr->sin6_addr);
+ if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
+ fl6.flowi6_oif = dst_addr->sin6_scope_id;
- *dst = ip6_route_output(&init_net, NULL, &fl);
+ *dst = ip6_route_output(&init_net, NULL, &fl6);
if (*dst)
return 0;
#endif
diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 4c4c74e..ba45e6b 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -183,10 +183,10 @@ extern void icmpv6_cleanup(void);
extern void icmpv6_param_prob(struct sk_buff *skb,
u8 code, int pos);
-struct flowi;
+struct flowi6;
struct in6_addr;
extern void icmpv6_flow_init(struct sock *sk,
- struct flowi *fl,
+ struct flowi6 *fl6,
u8 type,
const struct in6_addr *saddr,
const struct in6_addr *daddr,
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 46a6e8a..bc3cde0 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -183,7 +183,7 @@ struct fib6_table {
typedef struct rt6_info *(*pol_lookup_t)(struct net *,
struct fib6_table *,
- struct flowi *, int);
+ struct flowi6 *, int);
/*
* exported functions
@@ -192,7 +192,7 @@ typedef struct rt6_info *(*pol_lookup_t)(struct net *,
extern struct fib6_table *fib6_get_table(struct net *net, u32 id);
extern struct fib6_table *fib6_new_table(struct net *net, u32 id);
extern struct dst_entry *fib6_rule_lookup(struct net *net,
- struct flowi *fl, int flags,
+ struct flowi6 *fl6, int flags,
pol_lookup_t lookup);
extern struct fib6_node *fib6_lookup(struct fib6_node *root,
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 8552f0a..642a80b 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -71,7 +71,7 @@ extern void ip6_route_input(struct sk_buff *skb);
extern struct dst_entry * ip6_route_output(struct net *net,
struct sock *sk,
- struct flowi *fl);
+ struct flowi6 *fl6);
extern int ip6_route_init(void);
extern void ip6_route_cleanup(void);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 4635a5c..34200f9 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -492,7 +492,7 @@ extern int ip6_rcv_finish(struct sk_buff *skb);
*/
extern int ip6_xmit(struct sock *sk,
struct sk_buff *skb,
- struct flowi *fl,
+ struct flowi6 *fl6,
struct ipv6_txoptions *opt);
extern int ip6_nd_hdr(struct sock *sk,
@@ -512,7 +512,7 @@ extern int ip6_append_data(struct sock *sk,
int hlimit,
int tclass,
struct ipv6_txoptions *opt,
- struct flowi *fl,
+ struct flowi6 *fl6,
struct rt6_info *rt,
unsigned int flags,
int dontfrag);
@@ -523,13 +523,13 @@ extern void ip6_flush_pending_frames(struct sock *sk);
extern int ip6_dst_lookup(struct sock *sk,
struct dst_entry **dst,
- struct flowi *fl);
+ struct flowi6 *fl6);
extern struct dst_entry * ip6_dst_lookup_flow(struct sock *sk,
- struct flowi *fl,
+ struct flowi6 *fl6,
const struct in6_addr *final_dst,
bool can_sleep);
extern struct dst_entry * ip6_sk_dst_lookup_flow(struct sock *sk,
- struct flowi *fl,
+ struct flowi6 *fl6,
const struct in6_addr *final_dst,
bool can_sleep);
extern struct dst_entry * ip6_blackhole_route(struct net *net,
@@ -566,7 +566,7 @@ extern int ipv6_ext_hdr(u8 nexthdr);
extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
-extern struct in6_addr *fl6_update_dst(struct flowi *fl,
+extern struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
const struct ipv6_txoptions *opt,
struct in6_addr *orig);
@@ -600,8 +600,8 @@ extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
extern int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len);
extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
u32 info, u8 *payload);
-extern void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info);
-extern void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu);
+extern void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
+extern void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu);
extern int inet6_release(struct socket *sock);
extern int inet6_bind(struct socket *sock, struct sockaddr *uaddr,
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 42a0eb6..eeb077d 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -14,7 +14,7 @@ extern struct proto udpv6_prot;
extern struct proto udplitev6_prot;
extern struct proto tcpv6_prot;
-struct flowi;
+struct flowi6;
/* extention headers */
extern int ipv6_exthdrs_init(void);
@@ -42,7 +42,7 @@ extern int datagram_recv_ctl(struct sock *sk,
extern int datagram_send_ctl(struct net *net,
struct msghdr *msg,
- struct flowi *fl,
+ struct flowi6 *fl6,
struct ipv6_txoptions *opt,
int *hlimit, int *tclass,
int *dontfrag);
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 2b351c6..8d26c12 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -147,22 +147,22 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
dst = __sk_dst_check(sk, np->dst_cookie);
if (dst == NULL) {
struct inet_sock *inet = inet_sk(sk);
- struct flowi fl;
+ struct flowi6 fl6;
/* BUGGG_FUTURE: Again, it is not clear how
to handle rthdr case. Ignore this complexity
for now.
*/
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = IPPROTO_DCCP;
- ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
- ipv6_addr_copy(&fl.fl6_src, &np->saddr);
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.fl6_dport = inet->inet_dport;
- fl.fl6_sport = inet->inet_sport;
- security_sk_classify_flow(sk, &fl);
-
- dst = ip6_dst_lookup_flow(sk, &fl, NULL, false);
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_DCCP;
+ ipv6_addr_copy(&fl6.daddr, &np->daddr);
+ ipv6_addr_copy(&fl6.saddr, &np->saddr);
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.uli.ports.dport = inet->inet_dport;
+ fl6.uli.ports.sport = inet->inet_sport;
+ security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+
+ dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false);
if (IS_ERR(dst)) {
sk->sk_err_soft = -PTR_ERR(dst);
goto out;
@@ -243,25 +243,25 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
struct sk_buff *skb;
struct ipv6_txoptions *opt = NULL;
struct in6_addr *final_p, final;
- struct flowi fl;
+ struct flowi6 fl6;
int err = -1;
struct dst_entry *dst;
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = IPPROTO_DCCP;
- ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
- ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
- fl.fl6_flowlabel = 0;
- fl.flowi_oif = ireq6->iif;
- fl.fl6_dport = inet_rsk(req)->rmt_port;
- fl.fl6_sport = inet_rsk(req)->loc_port;
- security_req_classify_flow(req, &fl);
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_DCCP;
+ ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
+ ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
+ fl6.flowlabel = 0;
+ fl6.flowi6_oif = ireq6->iif;
+ fl6.uli.ports.dport = inet_rsk(req)->rmt_port;
+ fl6.uli.ports.sport = inet_rsk(req)->loc_port;
+ security_req_classify_flow(req, flowi6_to_flowi(&fl6));
opt = np->opt;
- final_p = fl6_update_dst(&fl, opt, &final);
+ final_p = fl6_update_dst(&fl6, opt, &final);
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, false);
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
dst = NULL;
@@ -275,8 +275,8 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
dh->dccph_checksum = dccp_v6_csum_finish(skb,
&ireq6->loc_addr,
&ireq6->rmt_addr);
- ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
- err = ip6_xmit(sk, skb, &fl, opt);
+ ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
+ err = ip6_xmit(sk, skb, &fl6, opt);
err = net_xmit_eval(err);
}
@@ -298,7 +298,7 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
{
struct ipv6hdr *rxip6h;
struct sk_buff *skb;
- struct flowi fl;
+ struct flowi6 fl6;
struct net *net = dev_net(skb_dst(rxskb)->dev);
struct sock *ctl_sk = net->dccp.v6_ctl_sk;
struct dst_entry *dst;
@@ -317,21 +317,21 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
dccp_hdr(skb)->dccph_checksum = dccp_v6_csum_finish(skb, &rxip6h->saddr,
&rxip6h->daddr);
- memset(&fl, 0, sizeof(fl));
- ipv6_addr_copy(&fl.fl6_dst, &rxip6h->saddr);
- ipv6_addr_copy(&fl.fl6_src, &rxip6h->daddr);
+ memset(&fl6, 0, sizeof(fl6));
+ ipv6_addr_copy(&fl6.daddr, &rxip6h->saddr);
+ ipv6_addr_copy(&fl6.saddr, &rxip6h->daddr);
- fl.flowi_proto = IPPROTO_DCCP;
- fl.flowi_oif = inet6_iif(rxskb);
- fl.fl6_dport = dccp_hdr(skb)->dccph_dport;
- fl.fl6_sport = dccp_hdr(skb)->dccph_sport;
- security_skb_classify_flow(rxskb, &fl);
+ fl6.flowi6_proto = IPPROTO_DCCP;
+ fl6.flowi6_oif = inet6_iif(rxskb);
+ fl6.uli.ports.dport = dccp_hdr(skb)->dccph_dport;
+ fl6.uli.ports.sport = dccp_hdr(skb)->dccph_sport;
+ security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6));
/* sk = NULL, but it is safe for now. RST socket required. */
- dst = ip6_dst_lookup_flow(ctl_sk, &fl, NULL, false);
+ dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false);
if (!IS_ERR(dst)) {
skb_dst_set(skb, dst);
- ip6_xmit(ctl_sk, skb, &fl, NULL);
+ ip6_xmit(ctl_sk, skb, &fl6, NULL);
DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
return;
@@ -527,19 +527,19 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
if (dst == NULL) {
struct in6_addr *final_p, final;
- struct flowi fl;
-
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = IPPROTO_DCCP;
- ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
- final_p = fl6_update_dst(&fl, opt, &final);
- ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.fl6_dport = inet_rsk(req)->rmt_port;
- fl.fl6_sport = inet_rsk(req)->loc_port;
- security_sk_classify_flow(sk, &fl);
-
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, false);
+ struct flowi6 fl6;
+
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_DCCP;
+ ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
+ final_p = fl6_update_dst(&fl6, opt, &final);
+ ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.uli.ports.dport = inet_rsk(req)->rmt_port;
+ fl6.uli.ports.sport = inet_rsk(req)->loc_port;
+ security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst))
goto out;
}
@@ -859,7 +859,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
struct ipv6_pinfo *np = inet6_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
struct in6_addr *saddr = NULL, *final_p, final;
- struct flowi fl;
+ struct flowi6 fl6;
struct dst_entry *dst;
int addr_type;
int err;
@@ -872,14 +872,14 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
if (usin->sin6_family != AF_INET6)
return -EAFNOSUPPORT;
- memset(&fl, 0, sizeof(fl));
+ memset(&fl6, 0, sizeof(fl6));
if (np->sndflow) {
- fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
- IP6_ECN_flow_init(fl.fl6_flowlabel);
- if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
+ fl6.flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
+ IP6_ECN_flow_init(fl6.flowlabel);
+ if (fl6.flowlabel & IPV6_FLOWLABEL_MASK) {
struct ip6_flowlabel *flowlabel;
- flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+ flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
if (flowlabel == NULL)
return -EINVAL;
ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
@@ -916,7 +916,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
}
ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
- np->flow_label = fl.fl6_flowlabel;
+ np->flow_label = fl6.flowlabel;
/*
* DCCP over IPv4
@@ -953,24 +953,24 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
if (!ipv6_addr_any(&np->rcv_saddr))
saddr = &np->rcv_saddr;
- fl.flowi_proto = IPPROTO_DCCP;
- ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
- ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr);
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.fl6_dport = usin->sin6_port;
- fl.fl6_sport = inet->inet_sport;
- security_sk_classify_flow(sk, &fl);
+ fl6.flowi6_proto = IPPROTO_DCCP;
+ ipv6_addr_copy(&fl6.daddr, &np->daddr);
+ ipv6_addr_copy(&fl6.saddr, saddr ? saddr : &np->saddr);
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.uli.ports.dport = usin->sin6_port;
+ fl6.uli.ports.sport = inet->inet_sport;
+ security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- final_p = fl6_update_dst(&fl, np->opt, &final);
+ final_p = fl6_update_dst(&fl6, np->opt, &final);
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, true);
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
goto failure;
}
if (saddr == NULL) {
- saddr = &fl.fl6_src;
+ saddr = &fl6.saddr;
ipv6_addr_copy(&np->rcv_saddr, saddr);
}
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 923febe..689eea6 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -652,22 +652,22 @@ int inet6_sk_rebuild_header(struct sock *sk)
if (dst == NULL) {
struct inet_sock *inet = inet_sk(sk);
struct in6_addr *final_p, final;
- struct flowi fl;
-
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = sk->sk_protocol;
- ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
- ipv6_addr_copy(&fl.fl6_src, &np->saddr);
- fl.fl6_flowlabel = np->flow_label;
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.flowi_mark = sk->sk_mark;
- fl.fl6_dport = inet->inet_dport;
- fl.fl6_sport = inet->inet_sport;
- security_sk_classify_flow(sk, &fl);
-
- final_p = fl6_update_dst(&fl, np->opt, &final);
-
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, false);
+ struct flowi6 fl6;
+
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = sk->sk_protocol;
+ ipv6_addr_copy(&fl6.daddr, &np->daddr);
+ ipv6_addr_copy(&fl6.saddr, &np->saddr);
+ fl6.flowlabel = np->flow_label;
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.flowi6_mark = sk->sk_mark;
+ fl6.uli.ports.dport = inet->inet_dport;
+ fl6.uli.ports.sport = inet->inet_sport;
+ security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+
+ final_p = fl6_update_dst(&fl6, np->opt, &final);
+
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
sk->sk_route_caps = 0;
sk->sk_err_soft = -PTR_ERR(dst);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 07e03e6..04ae676 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -40,7 +40,7 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
struct ipv6_pinfo *np = inet6_sk(sk);
struct in6_addr *daddr, *final_p, final;
struct dst_entry *dst;
- struct flowi fl;
+ struct flowi6 fl6;
struct ip6_flowlabel *flowlabel = NULL;
struct ipv6_txoptions *opt;
int addr_type;
@@ -59,11 +59,11 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
if (usin->sin6_family != AF_INET6)
return -EAFNOSUPPORT;
- memset(&fl, 0, sizeof(fl));
+ memset(&fl6, 0, sizeof(fl6));
if (np->sndflow) {
- fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
- if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
- flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+ fl6.flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+ if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
+ flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
if (flowlabel == NULL)
return -EINVAL;
ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
@@ -137,7 +137,7 @@ ipv4_connected:
}
ipv6_addr_copy(&np->daddr, daddr);
- np->flow_label = fl.fl6_flowlabel;
+ np->flow_label = fl6.flowlabel;
inet->inet_dport = usin->sin6_port;
@@ -146,23 +146,23 @@ ipv4_connected:
* destination cache for it.
*/
- fl.flowi_proto = sk->sk_protocol;
- ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
- ipv6_addr_copy(&fl.fl6_src, &np->saddr);
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.flowi_mark = sk->sk_mark;
- fl.fl6_dport = inet->inet_dport;
- fl.fl6_sport = inet->inet_sport;
+ fl6.flowi6_proto = sk->sk_protocol;
+ ipv6_addr_copy(&fl6.daddr, &np->daddr);
+ ipv6_addr_copy(&fl6.saddr, &np->saddr);
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.flowi6_mark = sk->sk_mark;
+ fl6.uli.ports.dport = inet->inet_dport;
+ fl6.uli.ports.sport = inet->inet_sport;
- if (!fl.flowi_oif && (addr_type&IPV6_ADDR_MULTICAST))
- fl.flowi_oif = np->mcast_oif;
+ if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST))
+ fl6.flowi6_oif = np->mcast_oif;
- security_sk_classify_flow(sk, &fl);
+ security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
opt = flowlabel ? flowlabel->opt : np->opt;
- final_p = fl6_update_dst(&fl, opt, &final);
+ final_p = fl6_update_dst(&fl6, opt, &final);
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, true);
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
err = 0;
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
@@ -172,20 +172,20 @@ ipv4_connected:
/* source address lookup done in ip6_dst_lookup */
if (ipv6_addr_any(&np->saddr))
- ipv6_addr_copy(&np->saddr, &fl.fl6_src);
+ ipv6_addr_copy(&np->saddr, &fl6.saddr);
if (ipv6_addr_any(&np->rcv_saddr)) {
- ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
+ ipv6_addr_copy(&np->rcv_saddr, &fl6.saddr);
inet->inet_rcv_saddr = LOOPBACK4_IPV6;
if (sk->sk_prot->rehash)
sk->sk_prot->rehash(sk);
}
ip6_dst_store(sk, dst,
- ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ?
+ ipv6_addr_equal(&fl6.daddr, &np->daddr) ?
&np->daddr : NULL,
#ifdef CONFIG_IPV6_SUBTREES
- ipv6_addr_equal(&fl.fl6_src, &np->saddr) ?
+ ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
&np->saddr :
#endif
NULL);
@@ -231,7 +231,7 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
kfree_skb(skb);
}
-void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info)
+void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct sock_exterr_skb *serr;
@@ -250,7 +250,7 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info)
skb_put(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
iph = ipv6_hdr(skb);
- ipv6_addr_copy(&iph->daddr, &fl->fl6_dst);
+ ipv6_addr_copy(&iph->daddr, &fl6->daddr);
serr = SKB_EXT_ERR(skb);
serr->ee.ee_errno = err;
@@ -261,7 +261,7 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info)
serr->ee.ee_info = info;
serr->ee.ee_data = 0;
serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
- serr->port = fl->fl6_dport;
+ serr->port = fl6->uli.ports.dport;
__skb_pull(skb, skb_tail_pointer(skb) - skb->data);
skb_reset_transport_header(skb);
@@ -270,7 +270,7 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info)
kfree_skb(skb);
}
-void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu)
+void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct ipv6hdr *iph;
@@ -287,7 +287,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu)
skb_put(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
iph = ipv6_hdr(skb);
- ipv6_addr_copy(&iph->daddr, &fl->fl6_dst);
+ ipv6_addr_copy(&iph->daddr, &fl6->daddr);
mtu_info = IP6CBMTU(skb);
if (!mtu_info) {
@@ -299,7 +299,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu)
mtu_info->ip6m_addr.sin6_family = AF_INET6;
mtu_info->ip6m_addr.sin6_port = 0;
mtu_info->ip6m_addr.sin6_flowinfo = 0;
- mtu_info->ip6m_addr.sin6_scope_id = fl->flowi_oif;
+ mtu_info->ip6m_addr.sin6_scope_id = fl6->flowi6_oif;
ipv6_addr_copy(&mtu_info->ip6m_addr.sin6_addr, &ipv6_hdr(skb)->daddr);
__skb_pull(skb, skb_tail_pointer(skb) - skb->data);
@@ -593,7 +593,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
}
int datagram_send_ctl(struct net *net,
- struct msghdr *msg, struct flowi *fl,
+ struct msghdr *msg, struct flowi6 *fl6,
struct ipv6_txoptions *opt,
int *hlimit, int *tclass, int *dontfrag)
{
@@ -629,16 +629,17 @@ int datagram_send_ctl(struct net *net,
src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
if (src_info->ipi6_ifindex) {
- if (fl->flowi_oif && src_info->ipi6_ifindex != fl->flowi_oif)
+ if (fl6->flowi6_oif &&
+ src_info->ipi6_ifindex != fl6->flowi6_oif)
return -EINVAL;
- fl->flowi_oif = src_info->ipi6_ifindex;
+ fl6->flowi6_oif = src_info->ipi6_ifindex;
}
addr_type = __ipv6_addr_type(&src_info->ipi6_addr);
rcu_read_lock();
- if (fl->flowi_oif) {
- dev = dev_get_by_index_rcu(net, fl->flowi_oif);
+ if (fl6->flowi6_oif) {
+ dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
if (!dev) {
rcu_read_unlock();
return -ENODEV;
@@ -654,7 +655,7 @@ int datagram_send_ctl(struct net *net,
strict ? dev : NULL, 0))
err = -EINVAL;
else
- ipv6_addr_copy(&fl->fl6_src, &src_info->ipi6_addr);
+ ipv6_addr_copy(&fl6->saddr, &src_info->ipi6_addr);
}
rcu_read_unlock();
@@ -671,13 +672,13 @@ int datagram_send_ctl(struct net *net,
goto exit_f;
}
- if (fl->fl6_flowlabel&IPV6_FLOWINFO_MASK) {
- if ((fl->fl6_flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
+ if (fl6->flowlabel&IPV6_FLOWINFO_MASK) {
+ if ((fl6->flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
err = -EINVAL;
goto exit_f;
}
}
- fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg);
+ fl6->flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg);
break;
case IPV6_2292HOPOPTS:
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 262f105..79a485e 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -876,22 +876,22 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
* fl6_update_dst - update flowi destination address with info given
* by srcrt option, if any.
*
- * @fl: flowi for which fl6_dst is to be updated
+ * @fl6: flowi6 for which daddr is to be updated
* @opt: struct ipv6_txoptions in which to look for srcrt opt
- * @orig: copy of original fl6_dst address if modified
+ * @orig: copy of original daddr address if modified
*
* Returns NULL if no txoptions or no srcrt, otherwise returns orig
- * and initial value of fl->fl6_dst set in orig
+ * and initial value of fl6->daddr set in orig
*/
-struct in6_addr *fl6_update_dst(struct flowi *fl,
+struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
const struct ipv6_txoptions *opt,
struct in6_addr *orig)
{
if (!opt || !opt->srcrt)
return NULL;
- ipv6_addr_copy(orig, &fl->fl6_dst);
- ipv6_addr_copy(&fl->fl6_dst, ((struct rt0_hdr *)opt->srcrt)->addr);
+ ipv6_addr_copy(orig, &fl6->daddr);
+ ipv6_addr_copy(&fl6->daddr, ((struct rt0_hdr *)opt->srcrt)->addr);
return orig;
}
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index d829874..34d244d 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -29,7 +29,7 @@ struct fib6_rule
u8 tclass;
};
-struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
+struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
int flags, pol_lookup_t lookup)
{
struct fib_lookup_arg arg = {
@@ -37,7 +37,8 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
.flags = FIB_LOOKUP_NOREF,
};
- fib_rules_lookup(net->ipv6.fib6_rules_ops, fl, flags, &arg);
+ fib_rules_lookup(net->ipv6.fib6_rules_ops,
+ flowi6_to_flowi(fl6), flags, &arg);
if (arg.result)
return arg.result;
@@ -49,6 +50,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
int flags, struct fib_lookup_arg *arg)
{
+ struct flowi6 *flp6 = &flp->u.ip6;
struct rt6_info *rt = NULL;
struct fib6_table *table;
struct net *net = rule->fr_net;
@@ -71,7 +73,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
table = fib6_get_table(net, rule->table);
if (table)
- rt = lookup(net, table, flp, flags);
+ rt = lookup(net, table, flp6, flags);
if (rt != net->ipv6.ip6_null_entry) {
struct fib6_rule *r = (struct fib6_rule *)rule;
@@ -86,14 +88,14 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
if (ipv6_dev_get_saddr(net,
ip6_dst_idev(&rt->dst)->dev,
- &flp->fl6_dst,
+ &flp6->daddr,
rt6_flags2srcprefs(flags),
&saddr))
goto again;
if (!ipv6_prefix_equal(&saddr, &r->src.addr,
r->src.plen))
goto again;
- ipv6_addr_copy(&flp->fl6_src, &saddr);
+ ipv6_addr_copy(&flp6->saddr, &saddr);
}
goto out;
}
@@ -113,9 +115,10 @@ out:
static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
{
struct fib6_rule *r = (struct fib6_rule *) rule;
+ struct flowi6 *fl6 = &fl->u.ip6;
if (r->dst.plen &&
- !ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen))
+ !ipv6_prefix_equal(&fl6->daddr, &r->dst.addr, r->dst.plen))
return 0;
/*
@@ -125,14 +128,14 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
*/
if (r->src.plen) {
if (flags & RT6_LOOKUP_F_HAS_SADDR) {
- if (!ipv6_prefix_equal(&fl->fl6_src, &r->src.addr,
+ if (!ipv6_prefix_equal(&fl6->saddr, &r->src.addr,
r->src.plen))
return 0;
} else if (!(r->common.flags & FIB_RULE_FIND_SADDR))
return 0;
}
- if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
+ if (r->tclass && r->tclass != ((ntohl(fl6->flowlabel) >> 20) & 0xff))
return 0;
return 1;
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 52ff7aa..f7b9041 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -158,7 +158,7 @@ static int is_ineligible(struct sk_buff *skb)
* Check the ICMP output rate limit
*/
static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
- struct flowi *fl)
+ struct flowi6 *fl6)
{
struct dst_entry *dst;
struct net *net = sock_net(sk);
@@ -177,7 +177,7 @@ static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
* XXX: perhaps the expire for routing entries cloned by
* this lookup should be more aggressive (not longer than timeout).
*/
- dst = ip6_route_output(net, sk, fl);
+ dst = ip6_route_output(net, sk, fl6);
if (dst->error) {
IP6_INC_STATS(net, ip6_dst_idev(dst),
IPSTATS_MIB_OUTNOROUTES);
@@ -217,7 +217,7 @@ static __inline__ int opt_unrec(struct sk_buff *skb, __u32 offset)
return (*op & 0xC0) == 0x80;
}
-static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len)
+static int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, struct icmp6hdr *thdr, int len)
{
struct sk_buff *skb;
struct icmp6hdr *icmp6h;
@@ -233,9 +233,9 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
if (skb_queue_len(&sk->sk_write_queue) == 1) {
skb->csum = csum_partial(icmp6h,
sizeof(struct icmp6hdr), skb->csum);
- icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src,
- &fl->fl6_dst,
- len, fl->flowi_proto,
+ icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr,
+ &fl6->daddr,
+ len, fl6->flowi6_proto,
skb->csum);
} else {
__wsum tmp_csum = 0;
@@ -246,9 +246,9 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
tmp_csum = csum_partial(icmp6h,
sizeof(struct icmp6hdr), tmp_csum);
- icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src,
- &fl->fl6_dst,
- len, fl->flowi_proto,
+ icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr,
+ &fl6->daddr,
+ len, fl6->flowi6_proto,
tmp_csum);
}
ip6_push_pending_frames(sk);
@@ -301,13 +301,13 @@ static inline void mip6_addr_swap(struct sk_buff *skb) {}
#endif
static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *skb,
- struct sock *sk, struct flowi *fl)
+ struct sock *sk, struct flowi6 *fl6)
{
struct dst_entry *dst, *dst2;
- struct flowi fl2;
+ struct flowi6 fl2;
int err;
- err = ip6_dst_lookup(sk, &dst, fl);
+ err = ip6_dst_lookup(sk, &dst, fl6);
if (err)
return ERR_PTR(err);
@@ -324,7 +324,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk
/* No need to clone since we're just using its address. */
dst2 = dst;
- dst = xfrm_lookup(net, dst, fl, sk, 0);
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(fl6), sk, 0);
if (!IS_ERR(dst)) {
if (dst != dst2)
return dst;
@@ -335,7 +335,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk
return dst;
}
- err = xfrm_decode_session_reverse(skb, &fl2, AF_INET6);
+ err = xfrm_decode_session_reverse(skb, flowi6_to_flowi(&fl2), AF_INET6);
if (err)
goto relookup_failed;
@@ -343,7 +343,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk
if (err)
goto relookup_failed;
- dst2 = xfrm_lookup(net, dst2, &fl2, sk, XFRM_LOOKUP_ICMP);
+ dst2 = xfrm_lookup(net, dst2, flowi6_to_flowi(&fl2), sk, XFRM_LOOKUP_ICMP);
if (!IS_ERR(dst2)) {
dst_release(dst);
dst = dst2;
@@ -375,7 +375,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
struct in6_addr *saddr = NULL;
struct dst_entry *dst;
struct icmp6hdr tmp_hdr;
- struct flowi fl;
+ struct flowi6 fl6;
struct icmpv6_msg msg;
int iif = 0;
int addr_type = 0;
@@ -442,22 +442,22 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
mip6_addr_swap(skb);
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = IPPROTO_ICMPV6;
- ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_ICMPV6;
+ ipv6_addr_copy(&fl6.daddr, &hdr->saddr);
if (saddr)
- ipv6_addr_copy(&fl.fl6_src, saddr);
- fl.flowi_oif = iif;
- fl.fl6_icmp_type = type;
- fl.fl6_icmp_code = code;
- security_skb_classify_flow(skb, &fl);
+ ipv6_addr_copy(&fl6.saddr, saddr);
+ fl6.flowi6_oif = iif;
+ fl6.uli.icmpt.type = type;
+ fl6.uli.icmpt.code = code;
+ security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
sk = icmpv6_xmit_lock(net);
if (sk == NULL)
return;
np = inet6_sk(sk);
- if (!icmpv6_xrlim_allow(sk, type, &fl))
+ if (!icmpv6_xrlim_allow(sk, type, &fl6))
goto out;
tmp_hdr.icmp6_type = type;
@@ -465,14 +465,14 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
tmp_hdr.icmp6_cksum = 0;
tmp_hdr.icmp6_pointer = htonl(info);
- if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst))
- fl.flowi_oif = np->mcast_oif;
+ if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
+ fl6.flowi6_oif = np->mcast_oif;
- dst = icmpv6_route_lookup(net, skb, sk, &fl);
+ dst = icmpv6_route_lookup(net, skb, sk, &fl6);
if (IS_ERR(dst))
goto out;
- if (ipv6_addr_is_multicast(&fl.fl6_dst))
+ if (ipv6_addr_is_multicast(&fl6.daddr))
hlimit = np->mcast_hops;
else
hlimit = np->hop_limit;
@@ -495,14 +495,14 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
err = ip6_append_data(sk, icmpv6_getfrag, &msg,
len + sizeof(struct icmp6hdr),
sizeof(struct icmp6hdr), hlimit,
- np->tclass, NULL, &fl, (struct rt6_info*)dst,
+ np->tclass, NULL, &fl6, (struct rt6_info*)dst,
MSG_DONTWAIT, np->dontfrag);
if (err) {
ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
ip6_flush_pending_frames(sk);
goto out_put;
}
- err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
+ err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, len + sizeof(struct icmp6hdr));
out_put:
if (likely(idev != NULL))
@@ -524,7 +524,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
struct in6_addr *saddr = NULL;
struct icmp6hdr *icmph = icmp6_hdr(skb);
struct icmp6hdr tmp_hdr;
- struct flowi fl;
+ struct flowi6 fl6;
struct icmpv6_msg msg;
struct dst_entry *dst;
int err = 0;
@@ -538,31 +538,31 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = IPPROTO_ICMPV6;
- ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_ICMPV6;
+ ipv6_addr_copy(&fl6.daddr, &ipv6_hdr(skb)->saddr);
if (saddr)
- ipv6_addr_copy(&fl.fl6_src, saddr);
- fl.flowi_oif = skb->dev->ifindex;
- fl.fl6_icmp_type = ICMPV6_ECHO_REPLY;
- security_skb_classify_flow(skb, &fl);
+ ipv6_addr_copy(&fl6.saddr, saddr);
+ fl6.flowi6_oif = skb->dev->ifindex;
+ fl6.uli.icmpt.type = ICMPV6_ECHO_REPLY;
+ security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
sk = icmpv6_xmit_lock(net);
if (sk == NULL)
return;
np = inet6_sk(sk);
- if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst))
- fl.flowi_oif = np->mcast_oif;
+ if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
+ fl6.flowi6_oif = np->mcast_oif;
- err = ip6_dst_lookup(sk, &dst, &fl);
+ err = ip6_dst_lookup(sk, &dst, &fl6);
if (err)
goto out;
- dst = xfrm_lookup(net, dst, &fl, sk, 0);
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0);
if (IS_ERR(dst))
goto out;
- if (ipv6_addr_is_multicast(&fl.fl6_dst))
+ if (ipv6_addr_is_multicast(&fl6.daddr))
hlimit = np->mcast_hops;
else
hlimit = np->hop_limit;
@@ -576,7 +576,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
msg.type = ICMPV6_ECHO_REPLY;
err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
- sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl,
+ sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl6,
(struct rt6_info*)dst, MSG_DONTWAIT,
np->dontfrag);
@@ -585,7 +585,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
ip6_flush_pending_frames(sk);
goto out_put;
}
- err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
+ err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
out_put:
if (likely(idev != NULL))
@@ -784,20 +784,20 @@ drop_no_count:
return 0;
}
-void icmpv6_flow_init(struct sock *sk, struct flowi *fl,
+void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6,
u8 type,
const struct in6_addr *saddr,
const struct in6_addr *daddr,
int oif)
{
- memset(fl, 0, sizeof(*fl));
- ipv6_addr_copy(&fl->fl6_src, saddr);
- ipv6_addr_copy(&fl->fl6_dst, daddr);
- fl->flowi_proto = IPPROTO_ICMPV6;
- fl->fl6_icmp_type = type;
- fl->fl6_icmp_code = 0;
- fl->flowi_oif = oif;
- security_sk_classify_flow(sk, fl);
+ memset(fl6, 0, sizeof(*fl6));
+ ipv6_addr_copy(&fl6->saddr, saddr);
+ ipv6_addr_copy(&fl6->daddr, daddr);
+ fl6->flowi6_proto = IPPROTO_ICMPV6;
+ fl6->uli.icmpt.type = type;
+ fl6->uli.icmpt.code = 0;
+ fl6->flowi6_oif = oif;
+ security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
}
/*
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 1b06a24..27d6691 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -61,20 +61,20 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk,
struct ipv6_pinfo *np = inet6_sk(sk);
struct in6_addr *final_p, final;
struct dst_entry *dst;
- struct flowi fl;
-
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = IPPROTO_TCP;
- ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
- final_p = fl6_update_dst(&fl, np->opt, &final);
- ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.flowi_mark = sk->sk_mark;
- fl.fl6_dport = inet_rsk(req)->rmt_port;
- fl.fl6_sport = inet_rsk(req)->loc_port;
- security_req_classify_flow(req, &fl);
-
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, false);
+ struct flowi6 fl6;
+
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr);
+ final_p = fl6_update_dst(&fl6, np->opt, &final);
+ ipv6_addr_copy(&fl6.saddr, &treq->loc_addr);
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.flowi6_mark = sk->sk_mark;
+ fl6.uli.ports.dport = inet_rsk(req)->rmt_port;
+ fl6.uli.ports.sport = inet_rsk(req)->loc_port;
+ security_req_classify_flow(req, flowi6_to_flowi(&fl6));
+
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst))
return NULL;
@@ -208,28 +208,28 @@ int inet6_csk_xmit(struct sk_buff *skb)
struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
- struct flowi fl;
+ struct flowi6 fl6;
struct dst_entry *dst;
struct in6_addr *final_p, final;
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = sk->sk_protocol;
- ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
- ipv6_addr_copy(&fl.fl6_src, &np->saddr);
- fl.fl6_flowlabel = np->flow_label;
- IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.flowi_mark = sk->sk_mark;
- fl.fl6_sport = inet->inet_sport;
- fl.fl6_dport = inet->inet_dport;
- security_sk_classify_flow(sk, &fl);
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = sk->sk_protocol;
+ ipv6_addr_copy(&fl6.daddr, &np->daddr);
+ ipv6_addr_copy(&fl6.saddr, &np->saddr);
+ fl6.flowlabel = np->flow_label;
+ IP6_ECN_flow_xmit(sk, fl6.flowlabel);
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.flowi6_mark = sk->sk_mark;
+ fl6.uli.ports.sport = inet->inet_sport;
+ fl6.uli.ports.dport = inet->inet_dport;
+ security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- final_p = fl6_update_dst(&fl, np->opt, &final);
+ final_p = fl6_update_dst(&fl6, np->opt, &final);
dst = __inet6_csk_dst_check(sk, np->dst_cookie);
if (dst == NULL) {
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, false);
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
sk->sk_err_soft = -PTR_ERR(dst);
@@ -244,9 +244,9 @@ int inet6_csk_xmit(struct sk_buff *skb)
skb_dst_set(skb, dst_clone(dst));
/* Restore final destination back after routing done */
- ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+ ipv6_addr_copy(&fl6.daddr, &np->daddr);
- return ip6_xmit(sk, skb, &fl, np->opt);
+ return ip6_xmit(sk, skb, &fl6, np->opt);
}
EXPORT_SYMBOL_GPL(inet6_csk_xmit);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index de38211..7548905 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -260,10 +260,10 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id)
return net->ipv6.fib6_main_tbl;
}
-struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
+struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
int flags, pol_lookup_t lookup)
{
- return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl, flags);
+ return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl6, flags);
}
static void __net_init fib6_tables_init(struct net *net)
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index c8fa470..f3caf1b 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -342,7 +342,7 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval,
if (olen > 0) {
struct msghdr msg;
- struct flowi flowi;
+ struct flowi6 flowi6;
int junk;
err = -ENOMEM;
@@ -358,9 +358,9 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval,
msg.msg_controllen = olen;
msg.msg_control = (void*)(fl->opt+1);
- flowi.flowi_oif = 0;
+ memset(&flowi6, 0, sizeof(flowi6));
- err = datagram_send_ctl(net, &msg, &flowi, fl->opt, &junk,
+ err = datagram_send_ctl(net, &msg, &flowi6, fl->opt, &junk,
&junk, &junk);
if (err)
goto done;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 3d0f2ac..1820887 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -174,15 +174,15 @@ int ip6_output(struct sk_buff *skb)
* xmit an sk_buff (used by TCP, SCTP and DCCP)
*/
-int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
+int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
struct ipv6_txoptions *opt)
{
struct net *net = sock_net(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
- struct in6_addr *first_hop = &fl->fl6_dst;
+ struct in6_addr *first_hop = &fl6->daddr;
struct dst_entry *dst = skb_dst(skb);
struct ipv6hdr *hdr;
- u8 proto = fl->flowi_proto;
+ u8 proto = fl6->flowi6_proto;
int seg_len = skb->len;
int hlimit = -1;
int tclass = 0;
@@ -230,13 +230,13 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
if (hlimit < 0)
hlimit = ip6_dst_hoplimit(dst);
- *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel;
+ *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl6->flowlabel;
hdr->payload_len = htons(seg_len);
hdr->nexthdr = proto;
hdr->hop_limit = hlimit;
- ipv6_addr_copy(&hdr->saddr, &fl->fl6_src);
+ ipv6_addr_copy(&hdr->saddr, &fl6->saddr);
ipv6_addr_copy(&hdr->daddr, first_hop);
skb->priority = sk->sk_priority;
@@ -879,7 +879,7 @@ static inline int ip6_rt_check(struct rt6key *rt_key,
static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
struct dst_entry *dst,
- struct flowi *fl)
+ struct flowi6 *fl6)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct rt6_info *rt = (struct rt6_info *)dst;
@@ -904,11 +904,11 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
* sockets.
* 2. oif also should be the same.
*/
- if (ip6_rt_check(&rt->rt6i_dst, &fl->fl6_dst, np->daddr_cache) ||
+ if (ip6_rt_check(&rt->rt6i_dst, &fl6->daddr, np->daddr_cache) ||
#ifdef CONFIG_IPV6_SUBTREES
- ip6_rt_check(&rt->rt6i_src, &fl->fl6_src, np->saddr_cache) ||
+ ip6_rt_check(&rt->rt6i_src, &fl6->saddr, np->saddr_cache) ||
#endif
- (fl->flowi_oif && fl->flowi_oif != dst->dev->ifindex)) {
+ (fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex)) {
dst_release(dst);
dst = NULL;
}
@@ -918,22 +918,22 @@ out:
}
static int ip6_dst_lookup_tail(struct sock *sk,
- struct dst_entry **dst, struct flowi *fl)
+ struct dst_entry **dst, struct flowi6 *fl6)
{
int err;
struct net *net = sock_net(sk);
if (*dst == NULL)
- *dst = ip6_route_output(net, sk, fl);
+ *dst = ip6_route_output(net, sk, fl6);
if ((err = (*dst)->error))
goto out_err_release;
- if (ipv6_addr_any(&fl->fl6_src)) {
+ if (ipv6_addr_any(&fl6->saddr)) {
err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
- &fl->fl6_dst,
+ &fl6->daddr,
sk ? inet6_sk(sk)->srcprefs : 0,
- &fl->fl6_src);
+ &fl6->saddr);
if (err)
goto out_err_release;
}
@@ -949,10 +949,10 @@ static int ip6_dst_lookup_tail(struct sock *sk,
*/
if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) {
struct inet6_ifaddr *ifp;
- struct flowi fl_gw;
+ struct flowi6 fl_gw6;
int redirect;
- ifp = ipv6_get_ifaddr(net, &fl->fl6_src,
+ ifp = ipv6_get_ifaddr(net, &fl6->saddr,
(*dst)->dev, 1);
redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
@@ -965,9 +965,9 @@ static int ip6_dst_lookup_tail(struct sock *sk,
* default router instead
*/
dst_release(*dst);
- memcpy(&fl_gw, fl, sizeof(struct flowi));
- memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
- *dst = ip6_route_output(net, sk, &fl_gw);
+ memcpy(&fl_gw6, fl6, sizeof(struct flowi6));
+ memset(&fl_gw6.daddr, 0, sizeof(struct in6_addr));
+ *dst = ip6_route_output(net, sk, &fl_gw6);
if ((err = (*dst)->error))
goto out_err_release;
}
@@ -988,23 +988,23 @@ out_err_release:
* ip6_dst_lookup - perform route lookup on flow
* @sk: socket which provides route info
* @dst: pointer to dst_entry * for result
- * @fl: flow to lookup
+ * @fl6: flow to lookup
*
* This function performs a route lookup on the given flow.
*
* It returns zero on success, or a standard errno code on error.
*/
-int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
+int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi6 *fl6)
{
*dst = NULL;
- return ip6_dst_lookup_tail(sk, dst, fl);
+ return ip6_dst_lookup_tail(sk, dst, fl6);
}
EXPORT_SYMBOL_GPL(ip6_dst_lookup);
/**
* ip6_dst_lookup_flow - perform route lookup on flow with ipsec
* @sk: socket which provides route info
- * @fl: flow to lookup
+ * @fl6: flow to lookup
* @final_dst: final destination address for ipsec lookup
* @can_sleep: we are in a sleepable context
*
@@ -1013,29 +1013,29 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup);
* It returns a valid dst pointer on success, or a pointer encoded
* error code.
*/
-struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi *fl,
+struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
const struct in6_addr *final_dst,
bool can_sleep)
{
struct dst_entry *dst = NULL;
int err;
- err = ip6_dst_lookup_tail(sk, &dst, fl);
+ err = ip6_dst_lookup_tail(sk, &dst, fl6);
if (err)
return ERR_PTR(err);
if (final_dst)
- ipv6_addr_copy(&fl->fl6_dst, final_dst);
+ ipv6_addr_copy(&fl6->daddr, final_dst);
if (can_sleep)
- fl->flowi_flags |= FLOWI_FLAG_CAN_SLEEP;
+ fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP;
- return xfrm_lookup(sock_net(sk), dst, fl, sk, 0);
+ return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
}
EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
/**
* ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow
* @sk: socket which provides the dst cache and route info
- * @fl: flow to lookup
+ * @fl6: flow to lookup
* @final_dst: final destination address for ipsec lookup
* @can_sleep: we are in a sleepable context
*
@@ -1047,24 +1047,24 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
* It returns a valid dst pointer on success, or a pointer encoded
* error code.
*/
-struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi *fl,
+struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
const struct in6_addr *final_dst,
bool can_sleep)
{
struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
int err;
- dst = ip6_sk_dst_check(sk, dst, fl);
+ dst = ip6_sk_dst_check(sk, dst, fl6);
- err = ip6_dst_lookup_tail(sk, &dst, fl);
+ err = ip6_dst_lookup_tail(sk, &dst, fl6);
if (err)
return ERR_PTR(err);
if (final_dst)
- ipv6_addr_copy(&fl->fl6_dst, final_dst);
+ ipv6_addr_copy(&fl6->daddr, final_dst);
if (can_sleep)
- fl->flowi_flags |= FLOWI_FLAG_CAN_SLEEP;
+ fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP;
- return xfrm_lookup(sock_net(sk), dst, fl, sk, 0);
+ return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
}
EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
@@ -1145,7 +1145,7 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
int offset, int len, int odd, struct sk_buff *skb),
void *from, int length, int transhdrlen,
- int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl,
+ int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6,
struct rt6_info *rt, unsigned int flags, int dontfrag)
{
struct inet_sock *inet = inet_sk(sk);
@@ -1203,7 +1203,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
}
dst_hold(&rt->dst);
inet->cork.dst = &rt->dst;
- inet->cork.fl = *fl;
+ inet->cork.fl.u.ip6 = *fl6;
np->cork.hop_limit = hlimit;
np->cork.tclass = tclass;
mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ?
@@ -1224,7 +1224,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
transhdrlen += exthdrlen;
} else {
rt = (struct rt6_info *)inet->cork.dst;
- fl = &inet->cork.fl;
+ fl6 = &inet->cork.fl.u.ip6;
opt = np->cork.opt;
transhdrlen = 0;
exthdrlen = 0;
@@ -1239,7 +1239,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) {
- ipv6_local_error(sk, EMSGSIZE, fl, mtu-exthdrlen);
+ ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen);
return -EMSGSIZE;
}
}
@@ -1271,7 +1271,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
if (length > mtu) {
int proto = sk->sk_protocol;
if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){
- ipv6_local_rxpmtu(sk, fl, mtu-exthdrlen);
+ ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen);
return -EMSGSIZE;
}
@@ -1516,8 +1516,8 @@ int ip6_push_pending_frames(struct sock *sk)
struct ipv6hdr *hdr;
struct ipv6_txoptions *opt = np->cork.opt;
struct rt6_info *rt = (struct rt6_info *)inet->cork.dst;
- struct flowi *fl = &inet->cork.fl;
- unsigned char proto = fl->flowi_proto;
+ struct flowi6 *fl6 = &inet->cork.fl.u.ip6;
+ unsigned char proto = fl6->flowi6_proto;
int err = 0;
if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL)
@@ -1542,7 +1542,7 @@ int ip6_push_pending_frames(struct sock *sk)
if (np->pmtudisc < IPV6_PMTUDISC_DO)
skb->local_df = 1;
- ipv6_addr_copy(final_dst, &fl->fl6_dst);
+ ipv6_addr_copy(final_dst, &fl6->daddr);
__skb_pull(skb, skb_network_header_len(skb));
if (opt && opt->opt_flen)
ipv6_push_frag_opts(skb, opt, &proto);
@@ -1553,12 +1553,12 @@ int ip6_push_pending_frames(struct sock *sk)
skb_reset_network_header(skb);
hdr = ipv6_hdr(skb);
- *(__be32*)hdr = fl->fl6_flowlabel |
+ *(__be32*)hdr = fl6->flowlabel |
htonl(0x60000000 | ((int)np->cork.tclass << 20));
hdr->hop_limit = np->cork.hop_limit;
hdr->nexthdr = proto;
- ipv6_addr_copy(&hdr->saddr, &fl->fl6_src);
+ ipv6_addr_copy(&hdr->saddr, &fl6->saddr);
ipv6_addr_copy(&hdr->daddr, final_dst);
skb->priority = sk->sk_priority;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index c3fc824..c1b1bd3 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -884,7 +884,7 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
static int ip6_tnl_xmit2(struct sk_buff *skb,
struct net_device *dev,
__u8 dsfield,
- struct flowi *fl,
+ struct flowi6 *fl6,
int encap_limit,
__u32 *pmtu)
{
@@ -904,11 +904,11 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
if ((dst = ip6_tnl_dst_check(t)) != NULL)
dst_hold(dst);
else {
- dst = ip6_route_output(net, NULL, fl);
+ dst = ip6_route_output(net, NULL, fl6);
if (dst->error)
goto tx_err_link_failure;
- dst = xfrm_lookup(net, dst, fl, NULL, 0);
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(fl6), NULL, 0);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
dst = NULL;
@@ -963,7 +963,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
skb->transport_header = skb->network_header;
- proto = fl->flowi_proto;
+ proto = fl6->flowi6_proto;
if (encap_limit >= 0) {
init_tel_txopt(&opt, encap_limit);
ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
@@ -971,13 +971,13 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
ipv6h = ipv6_hdr(skb);
- *(__be32*)ipv6h = fl->fl6_flowlabel | htonl(0x60000000);
+ *(__be32*)ipv6h = fl6->flowlabel | htonl(0x60000000);
dsfield = INET_ECN_encapsulate(0, dsfield);
ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
ipv6h->hop_limit = t->parms.hop_limit;
ipv6h->nexthdr = proto;
- ipv6_addr_copy(&ipv6h->saddr, &fl->fl6_src);
- ipv6_addr_copy(&ipv6h->daddr, &fl->fl6_dst);
+ ipv6_addr_copy(&ipv6h->saddr, &fl6->saddr);
+ ipv6_addr_copy(&ipv6h->daddr, &fl6->daddr);
nf_reset(skb);
pkt_len = skb->len;
err = ip6_local_out(skb);
@@ -1007,7 +1007,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
struct ip6_tnl *t = netdev_priv(dev);
struct iphdr *iph = ip_hdr(skb);
int encap_limit = -1;
- struct flowi fl;
+ struct flowi6 fl6;
__u8 dsfield;
__u32 mtu;
int err;
@@ -1019,16 +1019,16 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
encap_limit = t->parms.encap_limit;
- memcpy(&fl, &t->fl, sizeof (fl));
- fl.flowi_proto = IPPROTO_IPIP;
+ memcpy(&fl6, &t->fl.u.ip6, sizeof (fl6));
+ fl6.flowi6_proto = IPPROTO_IPIP;
dsfield = ipv4_get_dsfield(iph);
if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS))
- fl.fl6_flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT)
+ fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT)
& IPV6_TCLASS_MASK;
- err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu);
+ err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu);
if (err != 0) {
/* XXX: send ICMP error even if DF is not set. */
if (err == -EMSGSIZE)
@@ -1047,7 +1047,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
int encap_limit = -1;
__u16 offset;
- struct flowi fl;
+ struct flowi6 fl6;
__u8 dsfield;
__u32 mtu;
int err;
@@ -1069,16 +1069,16 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
} else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
encap_limit = t->parms.encap_limit;
- memcpy(&fl, &t->fl, sizeof (fl));
- fl.flowi_proto = IPPROTO_IPV6;
+ memcpy(&fl6, &t->fl.u.ip6, sizeof (fl6));
+ fl6.flowi6_proto = IPPROTO_IPV6;
dsfield = ipv6_get_dsfield(ipv6h);
if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS))
- fl.fl6_flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
+ fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
if ((t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL))
- fl.fl6_flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK);
+ fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK);
- err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu);
+ err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu);
if (err != 0) {
if (err == -EMSGSIZE)
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
@@ -1141,21 +1141,21 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
{
struct net_device *dev = t->dev;
struct ip6_tnl_parm *p = &t->parms;
- struct flowi *fl = &t->fl;
+ struct flowi6 *fl6 = &t->fl.u.ip6;
memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
/* Set up flowi template */
- ipv6_addr_copy(&fl->fl6_src, &p->laddr);
- ipv6_addr_copy(&fl->fl6_dst, &p->raddr);
- fl->flowi_oif = p->link;
- fl->fl6_flowlabel = 0;
+ ipv6_addr_copy(&fl6->saddr, &p->laddr);
+ ipv6_addr_copy(&fl6->daddr, &p->raddr);
+ fl6->flowi6_oif = p->link;
+ fl6->flowlabel = 0;
if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
- fl->fl6_flowlabel |= IPV6_TCLASS_MASK & p->flowinfo;
+ fl6->flowlabel |= IPV6_TCLASS_MASK & p->flowinfo;
if (!(p->flags&IP6_TNL_F_USE_ORIG_FLOWLABEL))
- fl->fl6_flowlabel |= IPV6_FLOWLABEL_MASK & p->flowinfo;
+ fl6->flowlabel |= IPV6_FLOWLABEL_MASK & p->flowinfo;
ip6_tnl_set_cap(t);
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 61a8be3..7ff0343 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -135,14 +135,15 @@ static struct mr6_table *ip6mr_get_table(struct net *net, u32 id)
return NULL;
}
-static int ip6mr_fib_lookup(struct net *net, struct flowi *flp,
+static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
struct mr6_table **mrt)
{
struct ip6mr_result res;
struct fib_lookup_arg arg = { .result = &res, };
int err;
- err = fib_rules_lookup(net->ipv6.mr6_rules_ops, flp, 0, &arg);
+ err = fib_rules_lookup(net->ipv6.mr6_rules_ops,
+ flowi6_to_flowi(flp6), 0, &arg);
if (err < 0)
return err;
*mrt = res.mrt;
@@ -270,7 +271,7 @@ static struct mr6_table *ip6mr_get_table(struct net *net, u32 id)
return net->ipv6.mrt6;
}
-static int ip6mr_fib_lookup(struct net *net, struct flowi *flp,
+static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
struct mr6_table **mrt)
{
*mrt = net->ipv6.mrt6;
@@ -617,9 +618,9 @@ static int pim6_rcv(struct sk_buff *skb)
struct net_device *reg_dev = NULL;
struct net *net = dev_net(skb->dev);
struct mr6_table *mrt;
- struct flowi fl = {
- .flowi_iif = skb->dev->ifindex,
- .flowi_mark = skb->mark,
+ struct flowi6 fl6 = {
+ .flowi6_iif = skb->dev->ifindex,
+ .flowi6_mark = skb->mark,
};
int reg_vif_num;
@@ -644,7 +645,7 @@ static int pim6_rcv(struct sk_buff *skb)
ntohs(encap->payload_len) + sizeof(*pim) > skb->len)
goto drop;
- if (ip6mr_fib_lookup(net, &fl, &mrt) < 0)
+ if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
goto drop;
reg_vif_num = mrt->mroute_reg_vif_num;
@@ -687,14 +688,14 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
{
struct net *net = dev_net(dev);
struct mr6_table *mrt;
- struct flowi fl = {
- .flowi_oif = dev->ifindex,
- .flowi_iif = skb->skb_iif,
- .flowi_mark = skb->mark,
+ struct flowi6 fl6 = {
+ .flowi6_oif = dev->ifindex,
+ .flowi6_iif = skb->skb_iif,
+ .flowi6_mark = skb->mark,
};
int err;
- err = ip6mr_fib_lookup(net, &fl, &mrt);
+ err = ip6mr_fib_lookup(net, &fl6, &mrt);
if (err < 0)
return err;
@@ -1547,13 +1548,13 @@ int ip6mr_sk_done(struct sock *sk)
struct sock *mroute6_socket(struct net *net, struct sk_buff *skb)
{
struct mr6_table *mrt;
- struct flowi fl = {
- .flowi_iif = skb->skb_iif,
- .flowi_oif = skb->dev->ifindex,
- .flowi_mark= skb->mark,
+ struct flowi6 fl6 = {
+ .flowi6_iif = skb->skb_iif,
+ .flowi6_oif = skb->dev->ifindex,
+ .flowi6_mark = skb->mark,
};
- if (ip6mr_fib_lookup(net, &fl, &mrt) < 0)
+ if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
return NULL;
return mrt->mroute6_sk;
@@ -1897,7 +1898,7 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt,
struct mif_device *vif = &mrt->vif6_table[vifi];
struct net_device *dev;
struct dst_entry *dst;
- struct flowi fl;
+ struct flowi6 fl6;
if (vif->dev == NULL)
goto out_free;
@@ -1915,12 +1916,12 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt,
ipv6h = ipv6_hdr(skb);
- fl = (struct flowi) {
- .flowi_oif = vif->link,
- .fl6_dst = ipv6h->daddr,
+ fl6 = (struct flowi6) {
+ .flowi6_oif = vif->link,
+ .daddr = ipv6h->daddr,
};
- dst = ip6_route_output(net, NULL, &fl);
+ dst = ip6_route_output(net, NULL, &fl6);
if (!dst)
goto out_free;
@@ -2043,13 +2044,13 @@ int ip6_mr_input(struct sk_buff *skb)
struct mfc6_cache *cache;
struct net *net = dev_net(skb->dev);
struct mr6_table *mrt;
- struct flowi fl = {
- .flowi_iif = skb->dev->ifindex,
- .flowi_mark= skb->mark,
+ struct flowi6 fl6 = {
+ .flowi6_iif = skb->dev->ifindex,
+ .flowi6_mark = skb->mark,
};
int err;
- err = ip6mr_fib_lookup(net, &fl, &mrt);
+ err = ip6mr_fib_lookup(net, &fl6, &mrt);
if (err < 0)
return err;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 1448c50..9cb191e 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -444,12 +444,12 @@ sticky_done:
{
struct ipv6_txoptions *opt = NULL;
struct msghdr msg;
- struct flowi fl;
+ struct flowi6 fl6;
int junk;
- fl.fl6_flowlabel = 0;
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.flowi_mark = sk->sk_mark;
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.flowi6_mark = sk->sk_mark;
if (optlen == 0)
goto update;
@@ -475,7 +475,7 @@ sticky_done:
msg.msg_controllen = optlen;
msg.msg_control = (void*)(opt+1);
- retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk,
+ retv = datagram_send_ctl(net, &msg, &fl6, opt, &junk, &junk,
&junk);
if (retv)
goto done;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index f2c9b69..76b8937 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1396,7 +1396,7 @@ static void mld_sendpack(struct sk_buff *skb)
struct inet6_dev *idev;
struct net *net = dev_net(skb->dev);
int err;
- struct flowi fl;
+ struct flowi6 fl6;
struct dst_entry *dst;
rcu_read_lock();
@@ -1419,11 +1419,11 @@ static void mld_sendpack(struct sk_buff *skb)
goto err_out;
}
- icmpv6_flow_init(net->ipv6.igmp_sk, &fl, ICMPV6_MLD2_REPORT,
+ icmpv6_flow_init(net->ipv6.igmp_sk, &fl6, ICMPV6_MLD2_REPORT,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
skb->dev->ifindex);
- dst = xfrm_lookup(net, dst, &fl, NULL, 0);
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
err = 0;
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
@@ -1731,7 +1731,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
u8 ra[8] = { IPPROTO_ICMPV6, 0,
IPV6_TLV_ROUTERALERT, 2, 0, 0,
IPV6_TLV_PADN, 0 };
- struct flowi fl;
+ struct flowi6 fl6;
struct dst_entry *dst;
if (type == ICMPV6_MGM_REDUCTION)
@@ -1791,11 +1791,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
goto err_out;
}
- icmpv6_flow_init(sk, &fl, type,
+ icmpv6_flow_init(sk, &fl6, type,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
skb->dev->ifindex);
- dst = xfrm_lookup(net, dst, &fl, NULL, 0);
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
goto err_out;
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index e1767ae..6a13735 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -208,14 +208,15 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb,
{
struct net *net = xs_net(x);
struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+ const struct flowi6 *fl6 = &fl->u.ip6;
struct ipv6_destopt_hao *hao = NULL;
struct xfrm_selector sel;
int offset;
struct timeval stamp;
int err = 0;
- if (unlikely(fl->flowi_proto == IPPROTO_MH &&
- fl->fl6_mh_type <= IP6_MH_TYPE_MAX))
+ if (unlikely(fl6->flowi6_proto == IPPROTO_MH &&
+ fl6->uli.mht.type <= IP6_MH_TYPE_MAX))
goto out;
if (likely(opt->dsthao)) {
@@ -240,14 +241,14 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb,
sizeof(sel.saddr));
sel.prefixlen_s = 128;
sel.family = AF_INET6;
- sel.proto = fl->flowi_proto;
- sel.dport = xfrm_flowi_dport(fl, &fl->u.ip6.uli);
+ sel.proto = fl6->flowi6_proto;
+ sel.dport = xfrm_flowi_dport(fl, &fl6->uli);
if (sel.dport)
sel.dport_mask = htons(~0);
- sel.sport = xfrm_flowi_sport(fl, &fl->u.ip6.uli);
+ sel.sport = xfrm_flowi_sport(fl, &fl6->uli);
if (sel.sport)
sel.sport_mask = htons(~0);
- sel.ifindex = fl->flowi_oif;
+ sel.ifindex = fl6->flowi6_oif;
err = km_report(net, IPPROTO_DSTOPTS, &sel,
(hao ? (xfrm_address_t *)&hao->addr : NULL));
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 9360d3b..0e49c9d 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -511,7 +511,7 @@ void ndisc_send_skb(struct sk_buff *skb,
const struct in6_addr *saddr,
struct icmp6hdr *icmp6h)
{
- struct flowi fl;
+ struct flowi6 fl6;
struct dst_entry *dst;
struct net *net = dev_net(dev);
struct sock *sk = net->ipv6.ndisc_sk;
@@ -521,7 +521,7 @@ void ndisc_send_skb(struct sk_buff *skb,
type = icmp6h->icmp6_type;
- icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex);
+ icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex);
dst = icmp6_dst_alloc(dev, neigh, daddr);
if (!dst) {
@@ -529,7 +529,7 @@ void ndisc_send_skb(struct sk_buff *skb,
return;
}
- dst = xfrm_lookup(net, dst, &fl, NULL, 0);
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
if (IS_ERR(dst)) {
kfree_skb(skb);
return;
@@ -1515,7 +1515,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
struct rt6_info *rt;
struct dst_entry *dst;
struct inet6_dev *idev;
- struct flowi fl;
+ struct flowi6 fl6;
u8 *opt;
int rd_len;
int err;
@@ -1535,14 +1535,14 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
return;
}
- icmpv6_flow_init(sk, &fl, NDISC_REDIRECT,
+ icmpv6_flow_init(sk, &fl6, NDISC_REDIRECT,
&saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
- dst = ip6_route_output(net, NULL, &fl);
+ dst = ip6_route_output(net, NULL, &fl6);
if (dst == NULL)
return;
- dst = xfrm_lookup(net, dst, &fl, NULL, 0);
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
if (IS_ERR(dst))
return;
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index d282c62..39aaca2 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -15,14 +15,14 @@ int ip6_route_me_harder(struct sk_buff *skb)
struct net *net = dev_net(skb_dst(skb)->dev);
struct ipv6hdr *iph = ipv6_hdr(skb);
struct dst_entry *dst;
- struct flowi fl = {
- .flowi_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
- .flowi_mark = skb->mark,
- .fl6_dst = iph->daddr,
- .fl6_src = iph->saddr,
+ struct flowi6 fl6 = {
+ .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
+ .flowi6_mark = skb->mark,
+ .daddr = iph->daddr,
+ .saddr = iph->saddr,
};
- dst = ip6_route_output(net, skb->sk, &fl);
+ dst = ip6_route_output(net, skb->sk, &fl6);
if (dst->error) {
IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
@@ -37,9 +37,9 @@ int ip6_route_me_harder(struct sk_buff *skb)
#ifdef CONFIG_XFRM
if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
- xfrm_decode_session(skb, &fl, AF_INET6) == 0) {
+ xfrm_decode_session(skb, flowi6_to_flowi(&fl6), AF_INET6) == 0) {
skb_dst_set(skb, NULL);
- dst = xfrm_lookup(net, dst, &fl, skb->sk, 0);
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), skb->sk, 0);
if (IS_ERR(dst))
return -1;
skb_dst_set(skb, dst);
@@ -92,7 +92,7 @@ static int nf_ip6_reroute(struct sk_buff *skb,
static int nf_ip6_route(struct dst_entry **dst, struct flowi *fl)
{
- *dst = ip6_route_output(&init_net, NULL, fl);
+ *dst = ip6_route_output(&init_net, NULL, &fl->u.ip6);
return (*dst)->error;
}
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index d1e905b..df05511 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -47,7 +47,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
struct ipv6hdr *ip6h;
struct dst_entry *dst = NULL;
u8 proto;
- struct flowi fl;
+ struct flowi6 fl6;
if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
(!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
@@ -89,19 +89,19 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
return;
}
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = IPPROTO_TCP;
- ipv6_addr_copy(&fl.fl6_src, &oip6h->daddr);
- ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr);
- fl.fl6_sport = otcph.dest;
- fl.fl6_dport = otcph.source;
- security_skb_classify_flow(oldskb, &fl);
- dst = ip6_route_output(net, NULL, &fl);
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl6.saddr, &oip6h->daddr);
+ ipv6_addr_copy(&fl6.daddr, &oip6h->saddr);
+ fl6.uli.ports.sport = otcph.dest;
+ fl6.uli.ports.dport = otcph.source;
+ security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6));
+ dst = ip6_route_output(net, NULL, &fl6);
if (dst == NULL || dst->error) {
dst_release(dst);
return;
}
- dst = xfrm_lookup(net, dst, &fl, NULL, 0);
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
if (IS_ERR(dst))
return;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index d061465..259f1b2 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -524,7 +524,7 @@ csum_copy_err:
goto out;
}
-static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
+static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
struct raw6_sock *rp)
{
struct sk_buff *skb;
@@ -586,11 +586,10 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
if (unlikely(csum))
tmp_csum = csum_sub(tmp_csum, csum_unfold(csum));
- csum = csum_ipv6_magic(&fl->fl6_src,
- &fl->fl6_dst,
- total_len, fl->flowi_proto, tmp_csum);
+ csum = csum_ipv6_magic(&fl6->saddr, &fl6->daddr,
+ total_len, fl6->flowi6_proto, tmp_csum);
- if (csum == 0 && fl->flowi_proto == IPPROTO_UDP)
+ if (csum == 0 && fl6->flowi6_proto == IPPROTO_UDP)
csum = CSUM_MANGLED_0;
if (skb_store_bits(skb, offset, &csum, 2))
@@ -603,7 +602,7 @@ out:
}
static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
- struct flowi *fl, struct dst_entry **dstp,
+ struct flowi6 *fl6, struct dst_entry **dstp,
unsigned int flags)
{
struct ipv6_pinfo *np = inet6_sk(sk);
@@ -613,7 +612,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
struct rt6_info *rt = (struct rt6_info *)*dstp;
if (length > rt->dst.dev->mtu) {
- ipv6_local_error(sk, EMSGSIZE, fl, rt->dst.dev->mtu);
+ ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu);
return -EMSGSIZE;
}
if (flags&MSG_PROBE)
@@ -662,7 +661,7 @@ error:
return err;
}
-static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
+static int rawv6_probe_proto_opt(struct flowi6 *fl6, struct msghdr *msg)
{
struct iovec *iov;
u8 __user *type = NULL;
@@ -679,7 +678,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
if (!iov)
continue;
- switch (fl->flowi_proto) {
+ switch (fl6->flowi6_proto) {
case IPPROTO_ICMPV6:
/* check if one-byte field is readable or not. */
if (iov->iov_base && iov->iov_len < 1)
@@ -694,8 +693,8 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
code = iov->iov_base;
if (type && code) {
- if (get_user(fl->fl6_icmp_type, type) ||
- get_user(fl->fl6_icmp_code, code))
+ if (get_user(fl6->uli.icmpt.type, type) ||
+ get_user(fl6->uli.icmpt.code, code))
return -EFAULT;
probed = 1;
}
@@ -706,7 +705,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
/* check if type field is readable or not. */
if (iov->iov_len > 2 - len) {
u8 __user *p = iov->iov_base;
- if (get_user(fl->fl6_mh_type, &p[2 - len]))
+ if (get_user(fl6->uli.mht.type, &p[2 - len]))
return -EFAULT;
probed = 1;
} else
@@ -735,7 +734,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
struct ipv6_txoptions *opt = NULL;
struct ip6_flowlabel *flowlabel = NULL;
struct dst_entry *dst = NULL;
- struct flowi fl;
+ struct flowi6 fl6;
int addr_len = msg->msg_namelen;
int hlimit = -1;
int tclass = -1;
@@ -756,9 +755,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
/*
* Get and verify the address.
*/
- memset(&fl, 0, sizeof(fl));
+ memset(&fl6, 0, sizeof(fl6));
- fl.flowi_mark = sk->sk_mark;
+ fl6.flowi6_mark = sk->sk_mark;
if (sin6) {
if (addr_len < SIN6_LEN_RFC2133)
@@ -780,9 +779,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
daddr = &sin6->sin6_addr;
if (np->sndflow) {
- fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
- if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
- flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+ fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+ if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
+ flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
if (flowlabel == NULL)
return -EINVAL;
daddr = &flowlabel->dst;
@@ -800,32 +799,32 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
if (addr_len >= sizeof(struct sockaddr_in6) &&
sin6->sin6_scope_id &&
ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
- fl.flowi_oif = sin6->sin6_scope_id;
+ fl6.flowi6_oif = sin6->sin6_scope_id;
} else {
if (sk->sk_state != TCP_ESTABLISHED)
return -EDESTADDRREQ;
proto = inet->inet_num;
daddr = &np->daddr;
- fl.fl6_flowlabel = np->flow_label;
+ fl6.flowlabel = np->flow_label;
}
- if (fl.flowi_oif == 0)
- fl.flowi_oif = sk->sk_bound_dev_if;
+ if (fl6.flowi6_oif == 0)
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
if (msg->msg_controllen) {
opt = &opt_space;
memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(struct ipv6_txoptions);
- err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit,
+ err = datagram_send_ctl(sock_net(sk), msg, &fl6, opt, &hlimit,
&tclass, &dontfrag);
if (err < 0) {
fl6_sock_release(flowlabel);
return err;
}
- if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
- flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+ if ((fl6.flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
+ flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
if (flowlabel == NULL)
return -EINVAL;
}
@@ -838,31 +837,31 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
opt = fl6_merge_options(&opt_space, flowlabel, opt);
opt = ipv6_fixup_options(&opt_space, opt);
- fl.flowi_proto = proto;
- err = rawv6_probe_proto_opt(&fl, msg);
+ fl6.flowi6_proto = proto;
+ err = rawv6_probe_proto_opt(&fl6, msg);
if (err)
goto out;
if (!ipv6_addr_any(daddr))
- ipv6_addr_copy(&fl.fl6_dst, daddr);
+ ipv6_addr_copy(&fl6.daddr, daddr);
else
- fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
- if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
- ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+ fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
+ if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
+ ipv6_addr_copy(&fl6.saddr, &np->saddr);
- final_p = fl6_update_dst(&fl, opt, &final);
+ final_p = fl6_update_dst(&fl6, opt, &final);
- if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst))
- fl.flowi_oif = np->mcast_oif;
- security_sk_classify_flow(sk, &fl);
+ if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
+ fl6.flowi6_oif = np->mcast_oif;
+ security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, true);
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
goto out;
}
if (hlimit < 0) {
- if (ipv6_addr_is_multicast(&fl.fl6_dst))
+ if (ipv6_addr_is_multicast(&fl6.daddr))
hlimit = np->mcast_hops;
else
hlimit = np->hop_limit;
@@ -881,17 +880,17 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
back_from_confirm:
if (inet->hdrincl)
- err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, &dst, msg->msg_flags);
+ err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl6, &dst, msg->msg_flags);
else {
lock_sock(sk);
err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
- len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst,
+ len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info*)dst,
msg->msg_flags, dontfrag);
if (err)
ip6_flush_pending_frames(sk);
else if (!(msg->msg_flags & MSG_MORE))
- err = rawv6_push_pending_frames(sk, &fl, rp);
+ err = rawv6_push_pending_frames(sk, &fl6, rp);
release_sock(sk);
}
done:
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c3b20d6..6814c87 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -599,17 +599,17 @@ do { \
static struct rt6_info *ip6_pol_route_lookup(struct net *net,
struct fib6_table *table,
- struct flowi *fl, int flags)
+ struct flowi6 *fl6, int flags)
{
struct fib6_node *fn;
struct rt6_info *rt;
read_lock_bh(&table->tb6_lock);
- fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
+ fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
restart:
rt = fn->leaf;
- rt = rt6_device_match(net, rt, &fl->fl6_src, fl->flowi_oif, flags);
- BACKTRACK(net, &fl->fl6_src);
+ rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags);
+ BACKTRACK(net, &fl6->saddr);
out:
dst_use(&rt->dst, jiffies);
read_unlock_bh(&table->tb6_lock);
@@ -620,19 +620,19 @@ out:
struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
const struct in6_addr *saddr, int oif, int strict)
{
- struct flowi fl = {
- .flowi_oif = oif,
- .fl6_dst = *daddr,
+ struct flowi6 fl6 = {
+ .flowi6_oif = oif,
+ .daddr = *daddr,
};
struct dst_entry *dst;
int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
if (saddr) {
- memcpy(&fl.fl6_src, saddr, sizeof(*saddr));
+ memcpy(&fl6.saddr, saddr, sizeof(*saddr));
flags |= RT6_LOOKUP_F_HAS_SADDR;
}
- dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_lookup);
+ dst = fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_lookup);
if (dst->error == 0)
return (struct rt6_info *) dst;
@@ -753,7 +753,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d
}
static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif,
- struct flowi *fl, int flags)
+ struct flowi6 *fl6, int flags)
{
struct fib6_node *fn;
struct rt6_info *rt, *nrt;
@@ -768,12 +768,12 @@ relookup:
read_lock_bh(&table->tb6_lock);
restart_2:
- fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
+ fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
restart:
rt = rt6_select(fn, oif, strict | reachable);
- BACKTRACK(net, &fl->fl6_src);
+ BACKTRACK(net, &fl6->saddr);
if (rt == net->ipv6.ip6_null_entry ||
rt->rt6i_flags & RTF_CACHE)
goto out;
@@ -782,9 +782,9 @@ restart:
read_unlock_bh(&table->tb6_lock);
if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
- nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
+ nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
else if (!(rt->dst.flags & DST_HOST))
- nrt = rt6_alloc_clone(rt, &fl->fl6_dst);
+ nrt = rt6_alloc_clone(rt, &fl6->daddr);
else
goto out2;
@@ -823,9 +823,9 @@ out2:
}
static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table,
- struct flowi *fl, int flags)
+ struct flowi6 *fl6, int flags)
{
- return ip6_pol_route(net, table, fl->flowi_iif, fl, flags);
+ return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
}
void ip6_route_input(struct sk_buff *skb)
@@ -833,41 +833,41 @@ void ip6_route_input(struct sk_buff *skb)
struct ipv6hdr *iph = ipv6_hdr(skb);
struct net *net = dev_net(skb->dev);
int flags = RT6_LOOKUP_F_HAS_SADDR;
- struct flowi fl = {
- .flowi_iif = skb->dev->ifindex,
- .fl6_dst = iph->daddr,
- .fl6_src = iph->saddr,
- .fl6_flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK,
- .flowi_mark = skb->mark,
- .flowi_proto = iph->nexthdr,
+ struct flowi6 fl6 = {
+ .flowi6_iif = skb->dev->ifindex,
+ .daddr = iph->daddr,
+ .saddr = iph->saddr,
+ .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK,
+ .flowi6_mark = skb->mark,
+ .flowi6_proto = iph->nexthdr,
};
if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG)
flags |= RT6_LOOKUP_F_IFACE;
- skb_dst_set(skb, fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input));
+ skb_dst_set(skb, fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_input));
}
static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
- struct flowi *fl, int flags)
+ struct flowi6 *fl6, int flags)
{
- return ip6_pol_route(net, table, fl->flowi_oif, fl, flags);
+ return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
}
struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
- struct flowi *fl)
+ struct flowi6 *fl6)
{
int flags = 0;
- if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl->fl6_dst))
+ if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr))
flags |= RT6_LOOKUP_F_IFACE;
- if (!ipv6_addr_any(&fl->fl6_src))
+ if (!ipv6_addr_any(&fl6->saddr))
flags |= RT6_LOOKUP_F_HAS_SADDR;
else if (sk)
flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
- return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output);
+ return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output);
}
EXPORT_SYMBOL(ip6_route_output);
@@ -1444,16 +1444,16 @@ static int ip6_route_del(struct fib6_config *cfg)
* Handle redirects
*/
struct ip6rd_flowi {
- struct flowi fl;
+ struct flowi6 fl6;
struct in6_addr gateway;
};
static struct rt6_info *__ip6_route_redirect(struct net *net,
struct fib6_table *table,
- struct flowi *fl,
+ struct flowi6 *fl6,
int flags)
{
- struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl;
+ struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6;
struct rt6_info *rt;
struct fib6_node *fn;
@@ -1469,7 +1469,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net,
*/
read_lock_bh(&table->tb6_lock);
- fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
+ fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
restart:
for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
/*
@@ -1484,7 +1484,7 @@ restart:
continue;
if (!(rt->rt6i_flags & RTF_GATEWAY))
continue;
- if (fl->flowi_oif != rt->rt6i_dev->ifindex)
+ if (fl6->flowi6_oif != rt->rt6i_dev->ifindex)
continue;
if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
continue;
@@ -1493,7 +1493,7 @@ restart:
if (!rt)
rt = net->ipv6.ip6_null_entry;
- BACKTRACK(net, &fl->fl6_src);
+ BACKTRACK(net, &fl6->saddr);
out:
dst_hold(&rt->dst);
@@ -1510,10 +1510,10 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
int flags = RT6_LOOKUP_F_HAS_SADDR;
struct net *net = dev_net(dev);
struct ip6rd_flowi rdfl = {
- .fl = {
- .flowi_oif = dev->ifindex,
- .fl6_dst = *dest,
- .fl6_src = *src,
+ .fl6 = {
+ .flowi6_oif = dev->ifindex,
+ .daddr = *dest,
+ .saddr = *src,
},
};
@@ -1522,7 +1522,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
if (rt6_need_strict(dest))
flags |= RT6_LOOKUP_F_IFACE;
- return (struct rt6_info *)fib6_rule_lookup(net, (struct flowi *)&rdfl,
+ return (struct rt6_info *)fib6_rule_lookup(net, &rdfl.fl6,
flags, __ip6_route_redirect);
}
@@ -2385,7 +2385,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
struct rt6_info *rt;
struct sk_buff *skb;
struct rtmsg *rtm;
- struct flowi fl;
+ struct flowi6 fl6;
int err, iif = 0;
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
@@ -2393,27 +2393,27 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
goto errout;
err = -EINVAL;
- memset(&fl, 0, sizeof(fl));
+ memset(&fl6, 0, sizeof(fl6));
if (tb[RTA_SRC]) {
if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
goto errout;
- ipv6_addr_copy(&fl.fl6_src, nla_data(tb[RTA_SRC]));
+ ipv6_addr_copy(&fl6.saddr, nla_data(tb[RTA_SRC]));
}
if (tb[RTA_DST]) {
if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr))
goto errout;
- ipv6_addr_copy(&fl.fl6_dst, nla_data(tb[RTA_DST]));
+ ipv6_addr_copy(&fl6.daddr, nla_data(tb[RTA_DST]));
}
if (tb[RTA_IIF])
iif = nla_get_u32(tb[RTA_IIF]);
if (tb[RTA_OIF])
- fl.flowi_oif = nla_get_u32(tb[RTA_OIF]);
+ fl6.flowi6_oif = nla_get_u32(tb[RTA_OIF]);
if (iif) {
struct net_device *dev;
@@ -2436,10 +2436,10 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
skb_reset_mac_header(skb);
skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
- rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl);
+ rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl6);
skb_dst_set(skb, &rt->dst);
- err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
+ err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,
RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
nlh->nlmsg_seq, 0, 0, 0);
if (err < 0) {
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 5b9eded..97858d5 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -232,19 +232,19 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
*/
{
struct in6_addr *final_p, final;
- struct flowi fl;
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = IPPROTO_TCP;
- ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
- final_p = fl6_update_dst(&fl, np->opt, &final);
- ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.flowi_mark = sk->sk_mark;
- fl.fl6_dport = inet_rsk(req)->rmt_port;
- fl.fl6_sport = inet_sk(sk)->inet_sport;
- security_req_classify_flow(req, &fl);
-
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, false);
+ struct flowi6 fl6;
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
+ final_p = fl6_update_dst(&fl6, np->opt, &final);
+ ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.flowi6_mark = sk->sk_mark;
+ fl6.uli.ports.dport = inet_rsk(req)->rmt_port;
+ fl6.uli.ports.sport = inet_sk(sk)->inet_sport;
+ security_req_classify_flow(req, flowi6_to_flowi(&fl6));
+
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst))
goto out_free;
}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index c531ad5..7ed0ba1 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -131,7 +131,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
struct tcp_sock *tp = tcp_sk(sk);
struct in6_addr *saddr = NULL, *final_p, final;
struct rt6_info *rt;
- struct flowi fl;
+ struct flowi6 fl6;
struct dst_entry *dst;
int addr_type;
int err;
@@ -142,14 +142,14 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
if (usin->sin6_family != AF_INET6)
return -EAFNOSUPPORT;
- memset(&fl, 0, sizeof(fl));
+ memset(&fl6, 0, sizeof(fl6));
if (np->sndflow) {
- fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
- IP6_ECN_flow_init(fl.fl6_flowlabel);
- if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
+ fl6.flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+ IP6_ECN_flow_init(fl6.flowlabel);
+ if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
struct ip6_flowlabel *flowlabel;
- flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+ flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
if (flowlabel == NULL)
return -EINVAL;
ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
@@ -195,7 +195,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
}
ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
- np->flow_label = fl.fl6_flowlabel;
+ np->flow_label = fl6.flowlabel;
/*
* TCP over IPv4
@@ -242,27 +242,27 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
if (!ipv6_addr_any(&np->rcv_saddr))
saddr = &np->rcv_saddr;
- fl.flowi_proto = IPPROTO_TCP;
- ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
- ipv6_addr_copy(&fl.fl6_src,
+ fl6.flowi6_proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl6.daddr, &np->daddr);
+ ipv6_addr_copy(&fl6.saddr,
(saddr ? saddr : &np->saddr));
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.flowi_mark = sk->sk_mark;
- fl.fl6_dport = usin->sin6_port;
- fl.fl6_sport = inet->inet_sport;
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.flowi6_mark = sk->sk_mark;
+ fl6.uli.ports.dport = usin->sin6_port;
+ fl6.uli.ports.sport = inet->inet_sport;
- final_p = fl6_update_dst(&fl, np->opt, &final);
+ final_p = fl6_update_dst(&fl6, np->opt, &final);
- security_sk_classify_flow(sk, &fl);
+ security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, true);
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
goto failure;
}
if (saddr == NULL) {
- saddr = &fl.fl6_src;
+ saddr = &fl6.saddr;
ipv6_addr_copy(&np->rcv_saddr, saddr);
}
@@ -389,23 +389,23 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
if (dst == NULL) {
struct inet_sock *inet = inet_sk(sk);
- struct flowi fl;
+ struct flowi6 fl6;
/* BUGGG_FUTURE: Again, it is not clear how
to handle rthdr case. Ignore this complexity
for now.
*/
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = IPPROTO_TCP;
- ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
- ipv6_addr_copy(&fl.fl6_src, &np->saddr);
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.flowi_mark = sk->sk_mark;
- fl.fl6_dport = inet->inet_dport;
- fl.fl6_sport = inet->inet_sport;
- security_skb_classify_flow(skb, &fl);
-
- dst = ip6_dst_lookup_flow(sk, &fl, NULL, false);
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl6.daddr, &np->daddr);
+ ipv6_addr_copy(&fl6.saddr, &np->saddr);
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
+ fl6.flowi6_mark = sk->sk_mark;
+ fl6.uli.ports.dport = inet->inet_dport;
+ fl6.uli.ports.sport = inet->inet_sport;
+ security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
+
+ dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false);
if (IS_ERR(dst)) {
sk->sk_err_soft = -PTR_ERR(dst);
goto out;
@@ -482,25 +482,25 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
struct sk_buff * skb;
struct ipv6_txoptions *opt = NULL;
struct in6_addr * final_p, final;
- struct flowi fl;
+ struct flowi6 fl6;
struct dst_entry *dst;
int err;
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = IPPROTO_TCP;
- ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
- ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
- fl.fl6_flowlabel = 0;
- fl.flowi_oif = treq->iif;
- fl.flowi_mark = sk->sk_mark;
- fl.fl6_dport = inet_rsk(req)->rmt_port;
- fl.fl6_sport = inet_rsk(req)->loc_port;
- security_req_classify_flow(req, &fl);
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr);
+ ipv6_addr_copy(&fl6.saddr, &treq->loc_addr);
+ fl6.flowlabel = 0;
+ fl6.flowi6_oif = treq->iif;
+ fl6.flowi6_mark = sk->sk_mark;
+ fl6.uli.ports.dport = inet_rsk(req)->rmt_port;
+ fl6.uli.ports.sport = inet_rsk(req)->loc_port;
+ security_req_classify_flow(req, flowi6_to_flowi(&fl6));
opt = np->opt;
- final_p = fl6_update_dst(&fl, opt, &final);
+ final_p = fl6_update_dst(&fl6, opt, &final);
- dst = ip6_dst_lookup_flow(sk, &fl, final_p, false);
+ dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
goto done;
@@ -510,8 +510,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
if (skb) {
__tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
- ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
- err = ip6_xmit(sk, skb, &fl, opt);
+ ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr);
+ err = ip6_xmit(sk, skb, &fl6, opt);
err = net_xmit_eval(err);
}
@@ -992,7 +992,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
{
struct tcphdr *th = tcp_hdr(skb), *t1;
struct sk_buff *buff;
- struct flowi fl;
+ struct flowi6 fl6;
struct net *net = dev_net(skb_dst(skb)->dev);
struct sock *ctl_sk = net->ipv6.tcp_sk;
unsigned int tot_len = sizeof(struct tcphdr);
@@ -1046,29 +1046,29 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
}
#endif
- memset(&fl, 0, sizeof(fl));
- ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
- ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
+ memset(&fl6, 0, sizeof(fl6));
+ ipv6_addr_copy(&fl6.daddr, &ipv6_hdr(skb)->saddr);
+ ipv6_addr_copy(&fl6.saddr, &ipv6_hdr(skb)->daddr);
buff->ip_summed = CHECKSUM_PARTIAL;
buff->csum = 0;
- __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst);
+ __tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr);
- fl.flowi_proto = IPPROTO_TCP;
- fl.flowi_oif = inet6_iif(skb);
- fl.fl6_dport = t1->dest;
- fl.fl6_sport = t1->source;
- security_skb_classify_flow(skb, &fl);
+ fl6.flowi6_proto = IPPROTO_TCP;
+ fl6.flowi6_oif = inet6_iif(skb);
+ fl6.uli.ports.dport = t1->dest;
+ fl6.uli.ports.sport = t1->source;
+ security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
/* Pass a socket to ip6_dst_lookup either it is for RST
* Underlying function will use this to retrieve the network
* namespace
*/
- dst = ip6_dst_lookup_flow(ctl_sk, &fl, NULL, false);
+ dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false);
if (!IS_ERR(dst)) {
skb_dst_set(buff, dst);
- ip6_xmit(ctl_sk, buff, &fl, NULL);
+ ip6_xmit(ctl_sk, buff, &fl6, NULL);
TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
if (rst)
TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index dad035f..ce4b16f 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -886,7 +886,7 @@ static int udp_v6_push_pending_frames(struct sock *sk)
struct udphdr *uh;
struct udp_sock *up = udp_sk(sk);
struct inet_sock *inet = inet_sk(sk);
- struct flowi *fl = &inet->cork.fl;
+ struct flowi6 *fl6 = &inet->cork.fl.u.ip6;
int err = 0;
int is_udplite = IS_UDPLITE(sk);
__wsum csum = 0;
@@ -899,23 +899,23 @@ static int udp_v6_push_pending_frames(struct sock *sk)
* Create a UDP header
*/
uh = udp_hdr(skb);
- uh->source = fl->fl6_sport;
- uh->dest = fl->fl6_dport;
+ uh->source = fl6->uli.ports.sport;
+ uh->dest = fl6->uli.ports.dport;
uh->len = htons(up->len);
uh->check = 0;
if (is_udplite)
csum = udplite_csum_outgoing(sk, skb);
else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
- udp6_hwcsum_outgoing(sk, skb, &fl->fl6_src, &fl->fl6_dst,
+ udp6_hwcsum_outgoing(sk, skb, &fl6->saddr, &fl6->daddr,
up->len);
goto send;
} else
csum = udp_csum_outgoing(sk, skb);
/* add protocol-dependent pseudo-header */
- uh->check = csum_ipv6_magic(&fl->fl6_src, &fl->fl6_dst,
- up->len, fl->flowi_proto, csum);
+ uh->check = csum_ipv6_magic(&fl6->saddr, &fl6->daddr,
+ up->len, fl6->flowi6_proto, csum);
if (uh->check == 0)
uh->check = CSUM_MANGLED_0;
@@ -947,7 +947,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
struct in6_addr *daddr, *final_p, final;
struct ipv6_txoptions *opt = NULL;
struct ip6_flowlabel *flowlabel = NULL;
- struct flowi fl;
+ struct flowi6 fl6;
struct dst_entry *dst;
int addr_len = msg->msg_namelen;
int ulen = len;
@@ -1030,19 +1030,19 @@ do_udp_sendmsg:
}
ulen += sizeof(struct udphdr);
- memset(&fl, 0, sizeof(fl));
+ memset(&fl6, 0, sizeof(fl6));
if (sin6) {
if (sin6->sin6_port == 0)
return -EINVAL;
- fl.fl6_dport = sin6->sin6_port;
+ fl6.uli.ports.dport = sin6->sin6_port;
daddr = &sin6->sin6_addr;
if (np->sndflow) {
- fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
- if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
- flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+ fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+ if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
+ flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
if (flowlabel == NULL)
return -EINVAL;
daddr = &flowlabel->dst;
@@ -1060,38 +1060,38 @@ do_udp_sendmsg:
if (addr_len >= sizeof(struct sockaddr_in6) &&
sin6->sin6_scope_id &&
ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
- fl.flowi_oif = sin6->sin6_scope_id;
+ fl6.flowi6_oif = sin6->sin6_scope_id;
} else {
if (sk->sk_state != TCP_ESTABLISHED)
return -EDESTADDRREQ;
- fl.fl6_dport = inet->inet_dport;
+ fl6.uli.ports.dport = inet->inet_dport;
daddr = &np->daddr;
- fl.fl6_flowlabel = np->flow_label;
+ fl6.flowlabel = np->flow_label;
connected = 1;
}
- if (!fl.flowi_oif)
- fl.flowi_oif = sk->sk_bound_dev_if;
+ if (!fl6.flowi6_oif)
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
- if (!fl.flowi_oif)
- fl.flowi_oif = np->sticky_pktinfo.ipi6_ifindex;
+ if (!fl6.flowi6_oif)
+ fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
- fl.flowi_mark = sk->sk_mark;
+ fl6.flowi6_mark = sk->sk_mark;
if (msg->msg_controllen) {
opt = &opt_space;
memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(*opt);
- err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit,
+ err = datagram_send_ctl(sock_net(sk), msg, &fl6, opt, &hlimit,
&tclass, &dontfrag);
if (err < 0) {
fl6_sock_release(flowlabel);
return err;
}
- if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
- flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+ if ((fl6.flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
+ flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
if (flowlabel == NULL)
return -EINVAL;
}
@@ -1105,27 +1105,27 @@ do_udp_sendmsg:
opt = fl6_merge_options(&opt_space, flowlabel, opt);
opt = ipv6_fixup_options(&opt_space, opt);
- fl.flowi_proto = sk->sk_protocol;
+ fl6.flowi6_proto = sk->sk_protocol;
if (!ipv6_addr_any(daddr))
- ipv6_addr_copy(&fl.fl6_dst, daddr);
+ ipv6_addr_copy(&fl6.daddr, daddr);
else
- fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
- if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
- ipv6_addr_copy(&fl.fl6_src, &np->saddr);
- fl.fl6_sport = inet->inet_sport;
+ fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
+ if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
+ ipv6_addr_copy(&fl6.saddr, &np->saddr);
+ fl6.uli.ports.sport = inet->inet_sport;
- final_p = fl6_update_dst(&fl, opt, &final);
+ final_p = fl6_update_dst(&fl6, opt, &final);
if (final_p)
connected = 0;
- if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) {
- fl.flowi_oif = np->mcast_oif;
+ if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) {
+ fl6.flowi6_oif = np->mcast_oif;
connected = 0;
}
- security_sk_classify_flow(sk, &fl);
+ security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- dst = ip6_sk_dst_lookup_flow(sk, &fl, final_p, true);
+ dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, true);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
dst = NULL;
@@ -1133,7 +1133,7 @@ do_udp_sendmsg:
}
if (hlimit < 0) {
- if (ipv6_addr_is_multicast(&fl.fl6_dst))
+ if (ipv6_addr_is_multicast(&fl6.daddr))
hlimit = np->mcast_hops;
else
hlimit = np->hop_limit;
@@ -1168,7 +1168,7 @@ do_append_data:
up->len += ulen;
getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen,
- sizeof(struct udphdr), hlimit, tclass, opt, &fl,
+ sizeof(struct udphdr), hlimit, tclass, opt, &fl6,
(struct rt6_info*)dst,
corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag);
if (err)
@@ -1181,10 +1181,10 @@ do_append_data:
if (dst) {
if (connected) {
ip6_dst_store(sk, dst,
- ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ?
+ ipv6_addr_equal(&fl6.daddr, &np->daddr) ?
&np->daddr : NULL,
#ifdef CONFIG_IPV6_SUBTREES
- ipv6_addr_equal(&fl.fl6_src, &np->saddr) ?
+ ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
&np->saddr :
#endif
NULL);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 254aa6d..bef6200 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -39,8 +39,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos,
if (saddr)
memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr));
- dst = ip6_route_output(net, NULL,
- flowi6_to_flowi(&fl6));
+ dst = ip6_route_output(net, NULL, &fl6);
err = dst->error;
if (dst->error) {
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index d07a32a..a60b20f 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -75,15 +75,13 @@ static int __ip_vs_addr_is_local_v6(struct net *net,
const struct in6_addr *addr)
{
struct rt6_info *rt;
- struct flowi fl = {
- .flowi_oif = 0,
- .fl6_dst = *addr,
- .fl6_src = { .s6_addr32 = {0, 0, 0, 0} },
+ struct flowi6 fl6 = {
+ .daddr = *addr,
};
- rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl);
+ rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6);
if (rt && rt->rt6i_dev && (rt->rt6i_dev->flags & IFF_LOOPBACK))
- return 1;
+ return 1;
return 0;
}
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 7dc00e3..6132b21 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -198,27 +198,27 @@ __ip_vs_route_output_v6(struct net *net, struct in6_addr *daddr,
struct in6_addr *ret_saddr, int do_xfrm)
{
struct dst_entry *dst;
- struct flowi fl = {
- .fl6_dst = *daddr,
+ struct flowi6 fl6 = {
+ .daddr = *daddr,
};
- dst = ip6_route_output(net, NULL, &fl);
+ dst = ip6_route_output(net, NULL, &fl6);
if (dst->error)
goto out_err;
if (!ret_saddr)
return dst;
- if (ipv6_addr_any(&fl.fl6_src) &&
+ if (ipv6_addr_any(&fl6.saddr) &&
ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
- &fl.fl6_dst, 0, &fl.fl6_src) < 0)
+ &fl6.daddr, 0, &fl6.saddr) < 0)
goto out_err;
if (do_xfrm) {
- dst = xfrm_lookup(net, dst, &fl, NULL, 0);
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
if (IS_ERR(dst)) {
dst = NULL;
goto out_err;
}
}
- ipv6_addr_copy(ret_saddr, &fl.fl6_src);
+ ipv6_addr_copy(ret_saddr, &fl6.saddr);
return dst;
out_err:
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
index d8c00f9..5f054a0 100644
--- a/net/netfilter/xt_TEE.c
+++ b/net/netfilter/xt_TEE.c
@@ -143,18 +143,18 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
const struct ipv6hdr *iph = ipv6_hdr(skb);
struct net *net = pick_net(skb);
struct dst_entry *dst;
- struct flowi fl;
+ struct flowi6 fl6;
- memset(&fl, 0, sizeof(fl));
+ memset(&fl6, 0, sizeof(fl6));
if (info->priv) {
if (info->priv->oif == -1)
return false;
- fl.flowi_oif = info->priv->oif;
+ fl6.flowi6_oif = info->priv->oif;
}
- fl.fl6_dst = info->gw.in6;
- fl.fl6_flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) |
+ fl6.daddr = info->gw.in6;
+ fl6.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) |
(iph->flow_lbl[1] << 8) | iph->flow_lbl[2];
- dst = ip6_route_output(net, NULL, &fl);
+ dst = ip6_route_output(net, NULL, &fl6);
if (dst == NULL)
return false;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 8316271..865ce7b 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -201,40 +201,40 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
{
struct sock *sk = skb->sk;
struct ipv6_pinfo *np = inet6_sk(sk);
- struct flowi fl;
+ struct flowi6 fl6;
- memset(&fl, 0, sizeof(fl));
+ memset(&fl6, 0, sizeof(fl6));
- fl.flowi_proto = sk->sk_protocol;
+ fl6.flowi6_proto = sk->sk_protocol;
/* Fill in the dest address from the route entry passed with the skb
* and the source address from the transport.
*/
- ipv6_addr_copy(&fl.fl6_dst, &transport->ipaddr.v6.sin6_addr);
- ipv6_addr_copy(&fl.fl6_src, &transport->saddr.v6.sin6_addr);
+ ipv6_addr_copy(&fl6.daddr, &transport->ipaddr.v6.sin6_addr);
+ ipv6_addr_copy(&fl6.saddr, &transport->saddr.v6.sin6_addr);
- fl.fl6_flowlabel = np->flow_label;
- IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
- if (ipv6_addr_type(&fl.fl6_src) & IPV6_ADDR_LINKLOCAL)
- fl.flowi_oif = transport->saddr.v6.sin6_scope_id;
+ fl6.flowlabel = np->flow_label;
+ IP6_ECN_flow_xmit(sk, fl6.flowlabel);
+ if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL)
+ fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id;
else
- fl.flowi_oif = sk->sk_bound_dev_if;
+ fl6.flowi6_oif = sk->sk_bound_dev_if;
if (np->opt && np->opt->srcrt) {
struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
- ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+ ipv6_addr_copy(&fl6.daddr, rt0->addr);
}
SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n",
__func__, skb, skb->len,
- &fl.fl6_src, &fl.fl6_dst);
+ &fl6.saddr, &fl6.daddr);
SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
if (!(transport->param_flags & SPP_PMTUD_ENABLE))
skb->local_df = 1;
- return ip6_xmit(sk, skb, &fl, np->opt);
+ return ip6_xmit(sk, skb, &fl6, np->opt);
}
/* Returns the dst cache entry for the given source and destination ip
@@ -245,22 +245,22 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
union sctp_addr *saddr)
{
struct dst_entry *dst;
- struct flowi fl;
+ struct flowi6 fl6;
- memset(&fl, 0, sizeof(fl));
- ipv6_addr_copy(&fl.fl6_dst, &daddr->v6.sin6_addr);
+ memset(&fl6, 0, sizeof(fl6));
+ ipv6_addr_copy(&fl6.daddr, &daddr->v6.sin6_addr);
if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
- fl.flowi_oif = daddr->v6.sin6_scope_id;
+ fl6.flowi6_oif = daddr->v6.sin6_scope_id;
- SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl.fl6_dst);
+ SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6.daddr);
if (saddr) {
- ipv6_addr_copy(&fl.fl6_src, &saddr->v6.sin6_addr);
- SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl.fl6_src);
+ ipv6_addr_copy(&fl6.saddr, &saddr->v6.sin6_addr);
+ SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6.saddr);
}
- dst = ip6_route_output(&init_net, NULL, &fl);
+ dst = ip6_route_output(&init_net, NULL, &fl6);
if (!dst->error) {
struct rt6_info *rt;
rt = (struct rt6_info *)dst;
--
1.7.4.1
^ permalink raw reply related
* [PATCH 24/25] net: Put fl6_* macros to struct flowi6 and use them again.
From: David Miller @ 2011-03-12 23:32 UTC (permalink / raw)
To: netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/flow.h | 17 +++++++----------
net/dccp/ipv6.c | 20 ++++++++++----------
net/ipv6/af_inet6.c | 4 ++--
net/ipv6/datagram.c | 6 +++---
net/ipv6/icmp.c | 10 +++++-----
net/ipv6/inet6_connection_sock.c | 8 ++++----
net/ipv6/mip6.c | 2 +-
net/ipv6/netfilter/ip6t_REJECT.c | 4 ++--
net/ipv6/raw.c | 6 +++---
net/ipv6/syncookies.c | 4 ++--
net/ipv6/tcp_ipv6.c | 16 ++++++++--------
net/ipv6/udp.c | 10 +++++-----
net/ipv6/xfrm6_policy.c | 12 ++++++------
13 files changed, 58 insertions(+), 61 deletions(-)
diff --git a/include/net/flow.h b/include/net/flow.h
index 44bd376..172d76d 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -84,6 +84,13 @@ struct flowi6 {
struct in6_addr saddr;
__be32 flowlabel;
union flowi_uli uli;
+#define fl6_sport uli.ports.sport
+#define fl6_dport uli.ports.dport
+#define fl6_icmp_type uli.icmpt.type
+#define fl6_icmp_code uli.icmpt.code
+#define fl6_ipsec_spi uli.spi
+#define fl6_mh_type uli.mht.type
+#define fl6_gre_key uli.gre_key
};
struct flowidn {
@@ -112,16 +119,6 @@ struct flowi {
#define fld_dst u.dn.daddr
#define fld_src u.dn.saddr
-#define fl6_dst u.ip6.daddr
-#define fl6_src u.ip6.saddr
-#define fl6_flowlabel u.ip6.flowlabel
-#define fl6_sport u.ip6.uli.ports.sport
-#define fl6_dport u.ip6.uli.ports.dport
-#define fl6_icmp_type u.ip6.uli.icmpt.type
-#define fl6_icmp_code u.ip6.uli.icmpt.code
-#define fl6_ipsec_spi u.ip6.uli.spi
-#define fl6_mh_type u.ip6.uli.mht.type
-#define fl6_gre_key u.ip6.uli.gre_key
} __attribute__((__aligned__(BITS_PER_LONG/8)));
static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4)
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 8d26c12..de1b7e3 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -158,8 +158,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
ipv6_addr_copy(&fl6.daddr, &np->daddr);
ipv6_addr_copy(&fl6.saddr, &np->saddr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
- fl6.uli.ports.dport = inet->inet_dport;
- fl6.uli.ports.sport = inet->inet_sport;
+ fl6.fl6_dport = inet->inet_dport;
+ fl6.fl6_sport = inet->inet_sport;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false);
@@ -253,8 +253,8 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
fl6.flowlabel = 0;
fl6.flowi6_oif = ireq6->iif;
- fl6.uli.ports.dport = inet_rsk(req)->rmt_port;
- fl6.uli.ports.sport = inet_rsk(req)->loc_port;
+ fl6.fl6_dport = inet_rsk(req)->rmt_port;
+ fl6.fl6_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, flowi6_to_flowi(&fl6));
opt = np->opt;
@@ -323,8 +323,8 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
fl6.flowi6_proto = IPPROTO_DCCP;
fl6.flowi6_oif = inet6_iif(rxskb);
- fl6.uli.ports.dport = dccp_hdr(skb)->dccph_dport;
- fl6.uli.ports.sport = dccp_hdr(skb)->dccph_sport;
+ fl6.fl6_dport = dccp_hdr(skb)->dccph_dport;
+ fl6.fl6_sport = dccp_hdr(skb)->dccph_sport;
security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6));
/* sk = NULL, but it is safe for now. RST socket required. */
@@ -535,8 +535,8 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
final_p = fl6_update_dst(&fl6, opt, &final);
ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
- fl6.uli.ports.dport = inet_rsk(req)->rmt_port;
- fl6.uli.ports.sport = inet_rsk(req)->loc_port;
+ fl6.fl6_dport = inet_rsk(req)->rmt_port;
+ fl6.fl6_sport = inet_rsk(req)->loc_port;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
@@ -957,8 +957,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
ipv6_addr_copy(&fl6.daddr, &np->daddr);
ipv6_addr_copy(&fl6.saddr, saddr ? saddr : &np->saddr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
- fl6.uli.ports.dport = usin->sin6_port;
- fl6.uli.ports.sport = inet->inet_sport;
+ fl6.fl6_dport = usin->sin6_port;
+ fl6.fl6_sport = inet->inet_sport;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
final_p = fl6_update_dst(&fl6, np->opt, &final);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 689eea6..4b13d5d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -661,8 +661,8 @@ int inet6_sk_rebuild_header(struct sock *sk)
fl6.flowlabel = np->flow_label;
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
- fl6.uli.ports.dport = inet->inet_dport;
- fl6.uli.ports.sport = inet->inet_sport;
+ fl6.fl6_dport = inet->inet_dport;
+ fl6.fl6_sport = inet->inet_sport;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
final_p = fl6_update_dst(&fl6, np->opt, &final);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 04ae676..1656033 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -151,8 +151,8 @@ ipv4_connected:
ipv6_addr_copy(&fl6.saddr, &np->saddr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
- fl6.uli.ports.dport = inet->inet_dport;
- fl6.uli.ports.sport = inet->inet_sport;
+ fl6.fl6_dport = inet->inet_dport;
+ fl6.fl6_sport = inet->inet_sport;
if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST))
fl6.flowi6_oif = np->mcast_oif;
@@ -261,7 +261,7 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info)
serr->ee.ee_info = info;
serr->ee.ee_data = 0;
serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
- serr->port = fl6->uli.ports.dport;
+ serr->port = fl6->fl6_dport;
__skb_pull(skb, skb_tail_pointer(skb) - skb->data);
skb_reset_transport_header(skb);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index f7b9041..83cb4f9 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -448,8 +448,8 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
if (saddr)
ipv6_addr_copy(&fl6.saddr, saddr);
fl6.flowi6_oif = iif;
- fl6.uli.icmpt.type = type;
- fl6.uli.icmpt.code = code;
+ fl6.fl6_icmp_type = type;
+ fl6.fl6_icmp_code = code;
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
sk = icmpv6_xmit_lock(net);
@@ -544,7 +544,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
if (saddr)
ipv6_addr_copy(&fl6.saddr, saddr);
fl6.flowi6_oif = skb->dev->ifindex;
- fl6.uli.icmpt.type = ICMPV6_ECHO_REPLY;
+ fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY;
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
sk = icmpv6_xmit_lock(net);
@@ -794,8 +794,8 @@ void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6,
ipv6_addr_copy(&fl6->saddr, saddr);
ipv6_addr_copy(&fl6->daddr, daddr);
fl6->flowi6_proto = IPPROTO_ICMPV6;
- fl6->uli.icmpt.type = type;
- fl6->uli.icmpt.code = 0;
+ fl6->fl6_icmp_type = type;
+ fl6->fl6_icmp_code = 0;
fl6->flowi6_oif = oif;
security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
}
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 27d6691..1660546 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -70,8 +70,8 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk,
ipv6_addr_copy(&fl6.saddr, &treq->loc_addr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
- fl6.uli.ports.dport = inet_rsk(req)->rmt_port;
- fl6.uli.ports.sport = inet_rsk(req)->loc_port;
+ fl6.fl6_dport = inet_rsk(req)->rmt_port;
+ fl6.fl6_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, flowi6_to_flowi(&fl6));
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
@@ -220,8 +220,8 @@ int inet6_csk_xmit(struct sk_buff *skb)
IP6_ECN_flow_xmit(sk, fl6.flowlabel);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
- fl6.uli.ports.sport = inet->inet_sport;
- fl6.uli.ports.dport = inet->inet_dport;
+ fl6.fl6_sport = inet->inet_sport;
+ fl6.fl6_dport = inet->inet_dport;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
final_p = fl6_update_dst(&fl6, np->opt, &final);
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 6a13735..9b21048 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -216,7 +216,7 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb,
int err = 0;
if (unlikely(fl6->flowi6_proto == IPPROTO_MH &&
- fl6->uli.mht.type <= IP6_MH_TYPE_MAX))
+ fl6->fl6_mh_type <= IP6_MH_TYPE_MAX))
goto out;
if (likely(opt->dsthao)) {
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index df05511..28e7448 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -93,8 +93,8 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
fl6.flowi6_proto = IPPROTO_TCP;
ipv6_addr_copy(&fl6.saddr, &oip6h->daddr);
ipv6_addr_copy(&fl6.daddr, &oip6h->saddr);
- fl6.uli.ports.sport = otcph.dest;
- fl6.uli.ports.dport = otcph.source;
+ fl6.fl6_sport = otcph.dest;
+ fl6.fl6_dport = otcph.source;
security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6));
dst = ip6_route_output(net, NULL, &fl6);
if (dst == NULL || dst->error) {
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 259f1b2..4a1c3b4 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -693,8 +693,8 @@ static int rawv6_probe_proto_opt(struct flowi6 *fl6, struct msghdr *msg)
code = iov->iov_base;
if (type && code) {
- if (get_user(fl6->uli.icmpt.type, type) ||
- get_user(fl6->uli.icmpt.code, code))
+ if (get_user(fl6->fl6_icmp_type, type) ||
+ get_user(fl6->fl6_icmp_code, code))
return -EFAULT;
probed = 1;
}
@@ -705,7 +705,7 @@ static int rawv6_probe_proto_opt(struct flowi6 *fl6, struct msghdr *msg)
/* check if type field is readable or not. */
if (iov->iov_len > 2 - len) {
u8 __user *p = iov->iov_base;
- if (get_user(fl6->uli.mht.type, &p[2 - len]))
+ if (get_user(fl6->fl6_mh_type, &p[2 - len]))
return -EFAULT;
probed = 1;
} else
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 97858d5..352c260 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -240,8 +240,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
- fl6.uli.ports.dport = inet_rsk(req)->rmt_port;
- fl6.uli.ports.sport = inet_sk(sk)->inet_sport;
+ fl6.fl6_dport = inet_rsk(req)->rmt_port;
+ fl6.fl6_sport = inet_sk(sk)->inet_sport;
security_req_classify_flow(req, flowi6_to_flowi(&fl6));
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 7ed0ba1..2b0c186 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -248,8 +248,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
(saddr ? saddr : &np->saddr));
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
- fl6.uli.ports.dport = usin->sin6_port;
- fl6.uli.ports.sport = inet->inet_sport;
+ fl6.fl6_dport = usin->sin6_port;
+ fl6.fl6_sport = inet->inet_sport;
final_p = fl6_update_dst(&fl6, np->opt, &final);
@@ -401,8 +401,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
ipv6_addr_copy(&fl6.saddr, &np->saddr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
- fl6.uli.ports.dport = inet->inet_dport;
- fl6.uli.ports.sport = inet->inet_sport;
+ fl6.fl6_dport = inet->inet_dport;
+ fl6.fl6_sport = inet->inet_sport;
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false);
@@ -493,8 +493,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
fl6.flowlabel = 0;
fl6.flowi6_oif = treq->iif;
fl6.flowi6_mark = sk->sk_mark;
- fl6.uli.ports.dport = inet_rsk(req)->rmt_port;
- fl6.uli.ports.sport = inet_rsk(req)->loc_port;
+ fl6.fl6_dport = inet_rsk(req)->rmt_port;
+ fl6.fl6_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, flowi6_to_flowi(&fl6));
opt = np->opt;
@@ -1057,8 +1057,8 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
fl6.flowi6_proto = IPPROTO_TCP;
fl6.flowi6_oif = inet6_iif(skb);
- fl6.uli.ports.dport = t1->dest;
- fl6.uli.ports.sport = t1->source;
+ fl6.fl6_dport = t1->dest;
+ fl6.fl6_sport = t1->source;
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
/* Pass a socket to ip6_dst_lookup either it is for RST
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index ce4b16f..d7037c0 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -899,8 +899,8 @@ static int udp_v6_push_pending_frames(struct sock *sk)
* Create a UDP header
*/
uh = udp_hdr(skb);
- uh->source = fl6->uli.ports.sport;
- uh->dest = fl6->uli.ports.dport;
+ uh->source = fl6->fl6_sport;
+ uh->dest = fl6->fl6_dport;
uh->len = htons(up->len);
uh->check = 0;
@@ -1036,7 +1036,7 @@ do_udp_sendmsg:
if (sin6->sin6_port == 0)
return -EINVAL;
- fl6.uli.ports.dport = sin6->sin6_port;
+ fl6.fl6_dport = sin6->sin6_port;
daddr = &sin6->sin6_addr;
if (np->sndflow) {
@@ -1065,7 +1065,7 @@ do_udp_sendmsg:
if (sk->sk_state != TCP_ESTABLISHED)
return -EDESTADDRREQ;
- fl6.uli.ports.dport = inet->inet_dport;
+ fl6.fl6_dport = inet->inet_dport;
daddr = &np->daddr;
fl6.flowlabel = np->flow_label;
connected = 1;
@@ -1112,7 +1112,7 @@ do_udp_sendmsg:
fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
ipv6_addr_copy(&fl6.saddr, &np->saddr);
- fl6.uli.ports.sport = inet->inet_sport;
+ fl6.fl6_sport = inet->inet_sport;
final_p = fl6_update_dst(&fl6, opt, &final);
if (final_p)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index bef6200..05e34c8 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -160,8 +160,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
pskb_may_pull(skb, nh + offset + 4 - skb->data))) {
__be16 *ports = (__be16 *)exthdr;
- fl6->uli.ports.sport = ports[!!reverse];
- fl6->uli.ports.dport = ports[!reverse];
+ fl6->fl6_sport = ports[!!reverse];
+ fl6->fl6_dport = ports[!reverse];
}
fl6->flowi6_proto = nexthdr;
return;
@@ -170,8 +170,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
u8 *icmp = (u8 *)exthdr;
- fl6->uli.icmpt.type = icmp[0];
- fl6->uli.icmpt.code = icmp[1];
+ fl6->fl6_icmp_type = icmp[0];
+ fl6->fl6_icmp_code = icmp[1];
}
fl6->flowi6_proto = nexthdr;
return;
@@ -182,7 +182,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
struct ip6_mh *mh;
mh = (struct ip6_mh *)exthdr;
- fl6->uli.mht.type = mh->ip6mh_type;
+ fl6->fl6_mh_type = mh->ip6mh_type;
}
fl6->flowi6_proto = nexthdr;
return;
@@ -193,7 +193,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
case IPPROTO_ESP:
case IPPROTO_COMP:
default:
- fl6->uli.spi = 0;
+ fl6->fl6_ipsec_spi = 0;
fl6->flowi6_proto = nexthdr;
return;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 25/25] decnet: Convert to use flowidn where applicable.
From: David Miller @ 2011-03-12 23:32 UTC (permalink / raw)
To: netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/dn.h | 6 +-
include/net/dn_fib.h | 8 +-
include/net/dn_route.h | 8 +-
include/net/flow.h | 12 ++-
net/decnet/af_decnet.c | 16 ++--
net/decnet/dn_fib.c | 23 ++--
net/decnet/dn_nsp_out.c | 16 ++--
net/decnet/dn_route.c | 269 ++++++++++++++++++++++++-----------------------
net/decnet/dn_rules.c | 17 ++--
net/decnet/dn_table.c | 6 +-
10 files changed, 196 insertions(+), 185 deletions(-)
diff --git a/include/net/dn.h b/include/net/dn.h
index 558dc7f..298521e 100644
--- a/include/net/dn.h
+++ b/include/net/dn.h
@@ -192,10 +192,10 @@ static inline void dn_dn2eth(unsigned char *ethaddr, __le16 addr)
ethaddr[5] = (__u8)(a >> 8);
}
-static inline void dn_sk_ports_copy(struct flowi *fl, struct dn_scp *scp)
+static inline void dn_sk_ports_copy(struct flowidn *fld, struct dn_scp *scp)
{
- fl->u.dn.uli.ports.sport = scp->addrloc;
- fl->u.dn.uli.ports.dport = scp->addrrem;
+ fld->fld_sport = scp->addrloc;
+ fld->fld_dport = scp->addrrem;
}
extern unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu);
diff --git a/include/net/dn_fib.h b/include/net/dn_fib.h
index bbcde32..782ef7c 100644
--- a/include/net/dn_fib.h
+++ b/include/net/dn_fib.h
@@ -98,7 +98,7 @@ struct dn_fib_table {
int (*delete)(struct dn_fib_table *t, struct rtmsg *r,
struct dn_kern_rta *rta, struct nlmsghdr *n,
struct netlink_skb_parms *req);
- int (*lookup)(struct dn_fib_table *t, const struct flowi *fl,
+ int (*lookup)(struct dn_fib_table *t, const struct flowidn *fld,
struct dn_fib_res *res);
int (*flush)(struct dn_fib_table *t);
int (*dump)(struct dn_fib_table *t, struct sk_buff *skb, struct netlink_callback *cb);
@@ -119,12 +119,12 @@ extern struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r,
struct dn_kern_rta *rta,
const struct nlmsghdr *nlh, int *errp);
extern int dn_fib_semantic_match(int type, struct dn_fib_info *fi,
- const struct flowi *fl,
+ const struct flowidn *fld,
struct dn_fib_res *res);
extern void dn_fib_release_info(struct dn_fib_info *fi);
extern __le16 dn_fib_get_attr16(struct rtattr *attr, int attrlen, int type);
extern void dn_fib_flush(void);
-extern void dn_fib_select_multipath(const struct flowi *fl,
+extern void dn_fib_select_multipath(const struct flowidn *fld,
struct dn_fib_res *res);
/*
@@ -141,7 +141,7 @@ extern void dn_fib_table_cleanup(void);
extern void dn_fib_rules_init(void);
extern void dn_fib_rules_cleanup(void);
extern unsigned dnet_addr_type(__le16 addr);
-extern int dn_fib_lookup(struct flowi *fl, struct dn_fib_res *res);
+extern int dn_fib_lookup(struct flowidn *fld, struct dn_fib_res *res);
extern int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb);
diff --git a/include/net/dn_route.h b/include/net/dn_route.h
index 1f59005..81712cf 100644
--- a/include/net/dn_route.h
+++ b/include/net/dn_route.h
@@ -16,7 +16,7 @@
*******************************************************************************/
extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri);
-extern int dn_route_output_sock(struct dst_entry **pprt, struct flowi *, struct sock *sk, int flags);
+extern int dn_route_output_sock(struct dst_entry **pprt, struct flowidn *, struct sock *sk, int flags);
extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb);
extern void dn_rt_cache_flush(int delay);
@@ -67,7 +67,7 @@ extern void dn_rt_cache_flush(int delay);
struct dn_route {
struct dst_entry dst;
- struct flowi fl;
+ struct flowidn fld;
__le16 rt_saddr;
__le16 rt_daddr;
@@ -82,12 +82,12 @@ struct dn_route {
static inline bool dn_is_input_route(struct dn_route *rt)
{
- return rt->fl.flowi_iif != 0;
+ return rt->fld.flowidn_iif != 0;
}
static inline bool dn_is_output_route(struct dn_route *rt)
{
- return rt->fl.flowi_iif == 0;
+ return rt->fld.flowidn_iif == 0;
}
extern void dn_route_init(void);
diff --git a/include/net/flow.h b/include/net/flow.h
index 172d76d..7fe5a0f 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -95,9 +95,17 @@ struct flowi6 {
struct flowidn {
struct flowi_common __fl_common;
+#define flowidn_oif __fl_common.flowic_oif
+#define flowidn_iif __fl_common.flowic_iif
+#define flowidn_mark __fl_common.flowic_mark
+#define flowidn_scope __fl_common.flowic_scope
+#define flowidn_proto __fl_common.flowic_proto
+#define flowidn_flags __fl_common.flowic_flags
__le16 daddr;
__le16 saddr;
union flowi_uli uli;
+#define fld_sport uli.ports.sport
+#define fld_dport uli.ports.dport
};
struct flowi {
@@ -115,10 +123,6 @@ struct flowi {
#define flowi_proto u.__fl_common.flowic_proto
#define flowi_flags u.__fl_common.flowic_flags
#define flowi_secid u.__fl_common.flowic_secid
-#define fld_scope flowi_scope
-
-#define fld_dst u.dn.daddr
-#define fld_src u.dn.saddr
} __attribute__((__aligned__(BITS_PER_LONG/8)));
static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4)
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index aafd15a..ea3b6ee 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -908,7 +908,7 @@ static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen,
struct socket *sock = sk->sk_socket;
struct dn_scp *scp = DN_SK(sk);
int err = -EISCONN;
- struct flowi fl;
+ struct flowidn fld;
if (sock->state == SS_CONNECTED)
goto out;
@@ -947,13 +947,13 @@ static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen,
memcpy(&scp->peer, addr, sizeof(struct sockaddr_dn));
err = -EHOSTUNREACH;
- memset(&fl, 0, sizeof(fl));
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.fld_dst = dn_saddr2dn(&scp->peer);
- fl.fld_src = dn_saddr2dn(&scp->addr);
- dn_sk_ports_copy(&fl, scp);
- fl.flowi_proto = DNPROTO_NSP;
- if (dn_route_output_sock(&sk->sk_dst_cache, &fl, sk, flags) < 0)
+ memset(&fld, 0, sizeof(fld));
+ fld.flowidn_oif = sk->sk_bound_dev_if;
+ fld.daddr = dn_saddr2dn(&scp->peer);
+ fld.saddr = dn_saddr2dn(&scp->addr);
+ dn_sk_ports_copy(&fld, scp);
+ fld.flowidn_proto = DNPROTO_NSP;
+ if (dn_route_output_sock(&sk->sk_dst_cache, &fld, sk, flags) < 0)
goto out;
sk->sk_route_caps = sk->sk_dst_cache->dev->features;
sock->state = SS_CONNECTING;
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index 4dfffa0..1c74ed3 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -201,7 +201,7 @@ static int dn_fib_check_nh(const struct rtmsg *r, struct dn_fib_info *fi, struct
int err;
if (nh->nh_gw) {
- struct flowi fl;
+ struct flowidn fld;
struct dn_fib_res res;
if (nh->nh_flags&RTNH_F_ONLINK) {
@@ -221,15 +221,15 @@ static int dn_fib_check_nh(const struct rtmsg *r, struct dn_fib_info *fi, struct
return 0;
}
- memset(&fl, 0, sizeof(fl));
- fl.fld_dst = nh->nh_gw;
- fl.flowi_oif = nh->nh_oif;
- fl.fld_scope = r->rtm_scope + 1;
+ memset(&fld, 0, sizeof(fld));
+ fld.daddr = nh->nh_gw;
+ fld.flowidn_oif = nh->nh_oif;
+ fld.flowidn_scope = r->rtm_scope + 1;
- if (fl.fld_scope < RT_SCOPE_LINK)
- fl.fld_scope = RT_SCOPE_LINK;
+ if (fld.flowidn_scope < RT_SCOPE_LINK)
+ fld.flowidn_scope = RT_SCOPE_LINK;
- if ((err = dn_fib_lookup(&fl, &res)) != 0)
+ if ((err = dn_fib_lookup(&fld, &res)) != 0)
return err;
err = -EINVAL;
@@ -404,7 +404,7 @@ failure:
return NULL;
}
-int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowi *fl, struct dn_fib_res *res)
+int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowidn *fld, struct dn_fib_res *res)
{
int err = dn_fib_props[type].error;
@@ -424,7 +424,8 @@ int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowi *
for_nexthops(fi) {
if (nh->nh_flags & RTNH_F_DEAD)
continue;
- if (!fl->flowi_oif || fl->flowi_oif == nh->nh_oif)
+ if (!fld->flowidn_oif ||
+ fld->flowidn_oif == nh->nh_oif)
break;
}
if (nhsel < fi->fib_nhs) {
@@ -445,7 +446,7 @@ int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowi *
return err;
}
-void dn_fib_select_multipath(const struct flowi *fl, struct dn_fib_res *res)
+void dn_fib_select_multipath(const struct flowidn *fld, struct dn_fib_res *res)
{
struct dn_fib_info *fi = res->fi;
int w;
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
index b3d6674..bd78836 100644
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -78,7 +78,7 @@ static void dn_nsp_send(struct sk_buff *skb)
struct sock *sk = skb->sk;
struct dn_scp *scp = DN_SK(sk);
struct dst_entry *dst;
- struct flowi fl;
+ struct flowidn fld;
skb_reset_transport_header(skb);
scp->stamp = jiffies;
@@ -91,13 +91,13 @@ try_again:
return;
}
- memset(&fl, 0, sizeof(fl));
- fl.flowi_oif = sk->sk_bound_dev_if;
- fl.fld_src = dn_saddr2dn(&scp->addr);
- fl.fld_dst = dn_saddr2dn(&scp->peer);
- dn_sk_ports_copy(&fl, scp);
- fl.flowi_proto = DNPROTO_NSP;
- if (dn_route_output_sock(&sk->sk_dst_cache, &fl, sk, 0) == 0) {
+ memset(&fld, 0, sizeof(fld));
+ fld.flowidn_oif = sk->sk_bound_dev_if;
+ fld.saddr = dn_saddr2dn(&scp->addr);
+ fld.daddr = dn_saddr2dn(&scp->peer);
+ dn_sk_ports_copy(&fld, scp);
+ fld.flowidn_proto = DNPROTO_NSP;
+ if (dn_route_output_sock(&sk->sk_dst_cache, &fld, sk, 0) == 0) {
dst = sk_dst_get(sk);
sk->sk_route_caps = dst->dev->features;
goto try_again;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index d74d34b..9f09d4f 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -282,14 +282,14 @@ static void dn_dst_link_failure(struct sk_buff *skb)
{
}
-static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
+static inline int compare_keys(struct flowidn *fl1, struct flowidn *fl2)
{
- return ((fl1->fld_dst ^ fl2->fld_dst) |
- (fl1->fld_src ^ fl2->fld_src) |
- (fl1->flowi_mark ^ fl2->flowi_mark) |
- (fl1->fld_scope ^ fl2->fld_scope) |
- (fl1->flowi_oif ^ fl2->flowi_oif) |
- (fl1->flowi_iif ^ fl2->flowi_iif)) == 0;
+ return ((fl1->daddr ^ fl2->daddr) |
+ (fl1->saddr ^ fl2->saddr) |
+ (fl1->flowidn_mark ^ fl2->flowidn_mark) |
+ (fl1->flowidn_scope ^ fl2->flowidn_scope) |
+ (fl1->flowidn_oif ^ fl2->flowidn_oif) |
+ (fl1->flowidn_iif ^ fl2->flowidn_iif)) == 0;
}
static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp)
@@ -303,7 +303,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route *
spin_lock_bh(&dn_rt_hash_table[hash].lock);
while ((rth = rcu_dereference_protected(*rthp,
lockdep_is_held(&dn_rt_hash_table[hash].lock))) != NULL) {
- if (compare_keys(&rth->fl, &rt->fl)) {
+ if (compare_keys(&rth->fld, &rt->fld)) {
/* Put it first */
*rthp = rth->dst.dn_next;
rcu_assign_pointer(rth->dst.dn_next,
@@ -903,15 +903,15 @@ static inline __le16 dn_fib_rules_map_destination(__le16 daddr, struct dn_fib_re
return (daddr&~mask)|res->fi->fib_nh->nh_gw;
}
-static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *oldflp, int try_hard)
+static int dn_route_output_slow(struct dst_entry **pprt, const struct flowidn *oldflp, int try_hard)
{
- struct flowi fl = {
- .fld_dst = oldflp->fld_dst,
- .fld_src = oldflp->fld_src,
- .fld_scope = RT_SCOPE_UNIVERSE,
- .flowi_mark = oldflp->flowi_mark,
- .flowi_iif = init_net.loopback_dev->ifindex,
- .flowi_oif = oldflp->flowi_oif,
+ struct flowidn fld = {
+ .daddr = oldflp->daddr,
+ .saddr = oldflp->saddr,
+ .flowidn_scope = RT_SCOPE_UNIVERSE,
+ .flowidn_mark = oldflp->flowidn_mark,
+ .flowidn_iif = init_net.loopback_dev->ifindex,
+ .flowidn_oif = oldflp->flowidn_oif,
};
struct dn_route *rt = NULL;
struct net_device *dev_out = NULL, *dev;
@@ -926,13 +926,14 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
if (decnet_debug_level & 16)
printk(KERN_DEBUG
"dn_route_output_slow: dst=%04x src=%04x mark=%d"
- " iif=%d oif=%d\n", le16_to_cpu(oldflp->fld_dst),
- le16_to_cpu(oldflp->fld_src),
- oldflp->flowi_mark, init_net.loopback_dev->ifindex, oldflp->flowi_oif);
+ " iif=%d oif=%d\n", le16_to_cpu(oldflp->daddr),
+ le16_to_cpu(oldflp->saddr),
+ oldflp->flowidn_mark, init_net.loopback_dev->ifindex,
+ oldflp->flowidn_oif);
/* If we have an output interface, verify its a DECnet device */
- if (oldflp->flowi_oif) {
- dev_out = dev_get_by_index(&init_net, oldflp->flowi_oif);
+ if (oldflp->flowidn_oif) {
+ dev_out = dev_get_by_index(&init_net, oldflp->flowidn_oif);
err = -ENODEV;
if (dev_out && dev_out->dn_ptr == NULL) {
dev_put(dev_out);
@@ -943,11 +944,11 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
}
/* If we have a source address, verify that its a local address */
- if (oldflp->fld_src) {
+ if (oldflp->saddr) {
err = -EADDRNOTAVAIL;
if (dev_out) {
- if (dn_dev_islocal(dev_out, oldflp->fld_src))
+ if (dn_dev_islocal(dev_out, oldflp->saddr))
goto source_ok;
dev_put(dev_out);
goto out;
@@ -956,11 +957,11 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
for_each_netdev_rcu(&init_net, dev) {
if (!dev->dn_ptr)
continue;
- if (!dn_dev_islocal(dev, oldflp->fld_src))
+ if (!dn_dev_islocal(dev, oldflp->saddr))
continue;
if ((dev->flags & IFF_LOOPBACK) &&
- oldflp->fld_dst &&
- !dn_dev_islocal(dev, oldflp->fld_dst))
+ oldflp->daddr &&
+ !dn_dev_islocal(dev, oldflp->daddr))
continue;
dev_out = dev;
@@ -975,22 +976,22 @@ source_ok:
}
/* No destination? Assume its local */
- if (!fl.fld_dst) {
- fl.fld_dst = fl.fld_src;
+ if (!fld.daddr) {
+ fld.daddr = fld.saddr;
err = -EADDRNOTAVAIL;
if (dev_out)
dev_put(dev_out);
dev_out = init_net.loopback_dev;
dev_hold(dev_out);
- if (!fl.fld_dst) {
- fl.fld_dst =
- fl.fld_src = dnet_select_source(dev_out, 0,
+ if (!fld.daddr) {
+ fld.daddr =
+ fld.saddr = dnet_select_source(dev_out, 0,
RT_SCOPE_HOST);
- if (!fl.fld_dst)
+ if (!fld.daddr)
goto out;
}
- fl.flowi_oif = init_net.loopback_dev->ifindex;
+ fld.flowidn_oif = init_net.loopback_dev->ifindex;
res.type = RTN_LOCAL;
goto make_route;
}
@@ -999,8 +1000,8 @@ source_ok:
printk(KERN_DEBUG
"dn_route_output_slow: initial checks complete."
" dst=%o4x src=%04x oif=%d try_hard=%d\n",
- le16_to_cpu(fl.fld_dst), le16_to_cpu(fl.fld_src),
- fl.flowi_oif, try_hard);
+ le16_to_cpu(fld.daddr), le16_to_cpu(fld.saddr),
+ fld.flowidn_oif, try_hard);
/*
* N.B. If the kernel is compiled without router support then
@@ -1008,7 +1009,7 @@ source_ok:
* will always be executed.
*/
err = -ESRCH;
- if (try_hard || (err = dn_fib_lookup(&fl, &res)) != 0) {
+ if (try_hard || (err = dn_fib_lookup(&fld, &res)) != 0) {
struct dn_dev *dn_db;
if (err != -ESRCH)
goto out;
@@ -1023,19 +1024,19 @@ source_ok:
* here
*/
if (!try_hard) {
- neigh = neigh_lookup_nodev(&dn_neigh_table, &init_net, &fl.fld_dst);
+ neigh = neigh_lookup_nodev(&dn_neigh_table, &init_net, &fld.daddr);
if (neigh) {
- if ((oldflp->flowi_oif &&
- (neigh->dev->ifindex != oldflp->flowi_oif)) ||
- (oldflp->fld_src &&
+ if ((oldflp->flowidn_oif &&
+ (neigh->dev->ifindex != oldflp->flowidn_oif)) ||
+ (oldflp->saddr &&
(!dn_dev_islocal(neigh->dev,
- oldflp->fld_src)))) {
+ oldflp->saddr)))) {
neigh_release(neigh);
neigh = NULL;
} else {
if (dev_out)
dev_put(dev_out);
- if (dn_dev_islocal(neigh->dev, fl.fld_dst)) {
+ if (dn_dev_islocal(neigh->dev, fld.daddr)) {
dev_out = init_net.loopback_dev;
res.type = RTN_LOCAL;
} else {
@@ -1055,7 +1056,7 @@ source_ok:
goto out;
dn_db = rcu_dereference_raw(dev_out->dn_ptr);
/* Possible improvement - check all devices for local addr */
- if (dn_dev_islocal(dev_out, fl.fld_dst)) {
+ if (dn_dev_islocal(dev_out, fld.daddr)) {
dev_put(dev_out);
dev_out = init_net.loopback_dev;
dev_hold(dev_out);
@@ -1071,16 +1072,16 @@ select_source:
if (neigh)
gateway = ((struct dn_neigh *)neigh)->addr;
if (gateway == 0)
- gateway = fl.fld_dst;
- if (fl.fld_src == 0) {
- fl.fld_src = dnet_select_source(dev_out, gateway,
- res.type == RTN_LOCAL ?
- RT_SCOPE_HOST :
- RT_SCOPE_LINK);
- if (fl.fld_src == 0 && res.type != RTN_LOCAL)
+ gateway = fld.daddr;
+ if (fld.saddr == 0) {
+ fld.saddr = dnet_select_source(dev_out, gateway,
+ res.type == RTN_LOCAL ?
+ RT_SCOPE_HOST :
+ RT_SCOPE_LINK);
+ if (fld.saddr == 0 && res.type != RTN_LOCAL)
goto e_addr;
}
- fl.flowi_oif = dev_out->ifindex;
+ fld.flowidn_oif = dev_out->ifindex;
goto make_route;
}
free_res = 1;
@@ -1089,35 +1090,35 @@ select_source:
goto e_inval;
if (res.type == RTN_LOCAL) {
- if (!fl.fld_src)
- fl.fld_src = fl.fld_dst;
+ if (!fld.saddr)
+ fld.saddr = fld.daddr;
if (dev_out)
dev_put(dev_out);
dev_out = init_net.loopback_dev;
dev_hold(dev_out);
- fl.flowi_oif = dev_out->ifindex;
+ fld.flowidn_oif = dev_out->ifindex;
if (res.fi)
dn_fib_info_put(res.fi);
res.fi = NULL;
goto make_route;
}
- if (res.fi->fib_nhs > 1 && fl.flowi_oif == 0)
- dn_fib_select_multipath(&fl, &res);
+ if (res.fi->fib_nhs > 1 && fld.flowidn_oif == 0)
+ dn_fib_select_multipath(&fld, &res);
/*
* We could add some logic to deal with default routes here and
* get rid of some of the special casing above.
*/
- if (!fl.fld_src)
- fl.fld_src = DN_FIB_RES_PREFSRC(res);
+ if (!fld.saddr)
+ fld.saddr = DN_FIB_RES_PREFSRC(res);
if (dev_out)
dev_put(dev_out);
dev_out = DN_FIB_RES_DEV(res);
dev_hold(dev_out);
- fl.flowi_oif = dev_out->ifindex;
+ fld.flowidn_oif = dev_out->ifindex;
gateway = DN_FIB_RES_GW(res);
make_route:
@@ -1131,19 +1132,19 @@ make_route:
atomic_set(&rt->dst.__refcnt, 1);
rt->dst.flags = DST_HOST;
- rt->fl.fld_src = oldflp->fld_src;
- rt->fl.fld_dst = oldflp->fld_dst;
- rt->fl.flowi_oif = oldflp->flowi_oif;
- rt->fl.flowi_iif = 0;
- rt->fl.flowi_mark = oldflp->flowi_mark;
+ rt->fld.saddr = oldflp->saddr;
+ rt->fld.daddr = oldflp->daddr;
+ rt->fld.flowidn_oif = oldflp->flowidn_oif;
+ rt->fld.flowidn_iif = 0;
+ rt->fld.flowidn_mark = oldflp->flowidn_mark;
- rt->rt_saddr = fl.fld_src;
- rt->rt_daddr = fl.fld_dst;
- rt->rt_gateway = gateway ? gateway : fl.fld_dst;
- rt->rt_local_src = fl.fld_src;
+ rt->rt_saddr = fld.saddr;
+ rt->rt_daddr = fld.daddr;
+ rt->rt_gateway = gateway ? gateway : fld.daddr;
+ rt->rt_local_src = fld.saddr;
- rt->rt_dst_map = fl.fld_dst;
- rt->rt_src_map = fl.fld_src;
+ rt->rt_dst_map = fld.daddr;
+ rt->rt_src_map = fld.saddr;
rt->dst.dev = dev_out;
dev_hold(dev_out);
@@ -1161,7 +1162,7 @@ make_route:
if (err)
goto e_neighbour;
- hash = dn_hash(rt->fl.fld_src, rt->fl.fld_dst);
+ hash = dn_hash(rt->fld.saddr, rt->fld.daddr);
dn_insert_route(rt, hash, (struct dn_route **)pprt);
done:
@@ -1192,20 +1193,20 @@ e_neighbour:
/*
* N.B. The flags may be moved into the flowi at some future stage.
*/
-static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *flp, int flags)
+static int __dn_route_output_key(struct dst_entry **pprt, const struct flowidn *flp, int flags)
{
- unsigned hash = dn_hash(flp->fld_src, flp->fld_dst);
+ unsigned hash = dn_hash(flp->saddr, flp->daddr);
struct dn_route *rt = NULL;
if (!(flags & MSG_TRYHARD)) {
rcu_read_lock_bh();
for (rt = rcu_dereference_bh(dn_rt_hash_table[hash].chain); rt;
rt = rcu_dereference_bh(rt->dst.dn_next)) {
- if ((flp->fld_dst == rt->fl.fld_dst) &&
- (flp->fld_src == rt->fl.fld_src) &&
- (flp->flowi_mark == rt->fl.flowi_mark) &&
+ if ((flp->daddr == rt->fld.daddr) &&
+ (flp->saddr == rt->fld.saddr) &&
+ (flp->flowidn_mark == rt->fld.flowidn_mark) &&
dn_is_output_route(rt) &&
- (rt->fl.flowi_oif == flp->flowi_oif)) {
+ (rt->fld.flowidn_oif == flp->flowidn_oif)) {
dst_use(&rt->dst, jiffies);
rcu_read_unlock_bh();
*pprt = &rt->dst;
@@ -1218,13 +1219,14 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl
return dn_route_output_slow(pprt, flp, flags);
}
-static int dn_route_output_key(struct dst_entry **pprt, struct flowi *flp, int flags)
+static int dn_route_output_key(struct dst_entry **pprt, struct flowidn *flp, int flags)
{
int err;
err = __dn_route_output_key(pprt, flp, flags);
- if (err == 0 && flp->flowi_proto) {
- *pprt = xfrm_lookup(&init_net, *pprt, flp, NULL, 0);
+ if (err == 0 && flp->flowidn_proto) {
+ *pprt = xfrm_lookup(&init_net, *pprt,
+ flowidn_to_flowi(flp), NULL, 0);
if (IS_ERR(*pprt)) {
err = PTR_ERR(*pprt);
*pprt = NULL;
@@ -1233,15 +1235,16 @@ static int dn_route_output_key(struct dst_entry **pprt, struct flowi *flp, int f
return err;
}
-int dn_route_output_sock(struct dst_entry **pprt, struct flowi *fl, struct sock *sk, int flags)
+int dn_route_output_sock(struct dst_entry **pprt, struct flowidn *fl, struct sock *sk, int flags)
{
int err;
err = __dn_route_output_key(pprt, fl, flags & MSG_TRYHARD);
- if (err == 0 && fl->flowi_proto) {
+ if (err == 0 && fl->flowidn_proto) {
if (!(flags & MSG_DONTWAIT))
- fl->flowi_flags |= FLOWI_FLAG_CAN_SLEEP;
- *pprt = xfrm_lookup(&init_net, *pprt, fl, sk, 0);
+ fl->flowidn_flags |= FLOWI_FLAG_CAN_SLEEP;
+ *pprt = xfrm_lookup(&init_net, *pprt,
+ flowidn_to_flowi(fl), sk, 0);
if (IS_ERR(*pprt)) {
err = PTR_ERR(*pprt);
*pprt = NULL;
@@ -1262,12 +1265,12 @@ static int dn_route_input_slow(struct sk_buff *skb)
int flags = 0;
__le16 gateway = 0;
__le16 local_src = 0;
- struct flowi fl = {
- .fld_dst = cb->dst,
- .fld_src = cb->src,
- .fld_scope = RT_SCOPE_UNIVERSE,
- .flowi_mark = skb->mark,
- .flowi_iif = skb->dev->ifindex,
+ struct flowidn fld = {
+ .daddr = cb->dst,
+ .saddr = cb->src,
+ .flowidn_scope = RT_SCOPE_UNIVERSE,
+ .flowidn_mark = skb->mark,
+ .flowidn_iif = skb->dev->ifindex,
};
struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE };
int err = -EINVAL;
@@ -1279,7 +1282,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
goto out;
/* Zero source addresses are not allowed */
- if (fl.fld_src == 0)
+ if (fld.saddr == 0)
goto out;
/*
@@ -1293,7 +1296,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
if (dn_dev_islocal(in_dev, cb->src))
goto out;
- err = dn_fib_lookup(&fl, &res);
+ err = dn_fib_lookup(&fld, &res);
if (err) {
if (err != -ESRCH)
goto out;
@@ -1305,7 +1308,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
res.type = RTN_LOCAL;
} else {
- __le16 src_map = fl.fld_src;
+ __le16 src_map = fld.saddr;
free_res = 1;
out_dev = DN_FIB_RES_DEV(res);
@@ -1318,22 +1321,22 @@ static int dn_route_input_slow(struct sk_buff *skb)
dev_hold(out_dev);
if (res.r)
- src_map = fl.fld_src; /* no NAT support for now */
+ src_map = fld.saddr; /* no NAT support for now */
gateway = DN_FIB_RES_GW(res);
if (res.type == RTN_NAT) {
- fl.fld_dst = dn_fib_rules_map_destination(fl.fld_dst, &res);
+ fld.daddr = dn_fib_rules_map_destination(fld.daddr, &res);
dn_fib_res_put(&res);
free_res = 0;
- if (dn_fib_lookup(&fl, &res))
+ if (dn_fib_lookup(&fld, &res))
goto e_inval;
free_res = 1;
if (res.type != RTN_UNICAST)
goto e_inval;
flags |= RTCF_DNAT;
- gateway = fl.fld_dst;
+ gateway = fld.daddr;
}
- fl.fld_src = src_map;
+ fld.saddr = src_map;
}
switch(res.type) {
@@ -1347,8 +1350,8 @@ static int dn_route_input_slow(struct sk_buff *skb)
if (dn_db->parms.forwarding == 0)
goto e_inval;
- if (res.fi->fib_nhs > 1 && fl.flowi_oif == 0)
- dn_fib_select_multipath(&fl, &res);
+ if (res.fi->fib_nhs > 1 && fld.flowidn_oif == 0)
+ dn_fib_select_multipath(&fld, &res);
/*
* Check for out_dev == in_dev. We use the RTCF_DOREDIRECT
@@ -1366,8 +1369,8 @@ static int dn_route_input_slow(struct sk_buff *skb)
break;
case RTN_LOCAL:
flags |= RTCF_LOCAL;
- fl.fld_src = cb->dst;
- fl.fld_dst = cb->src;
+ fld.saddr = cb->dst;
+ fld.daddr = cb->src;
/* Routing tables gave us a gateway */
if (gateway)
@@ -1400,21 +1403,21 @@ make_route:
if (rt == NULL)
goto e_nobufs;
- rt->rt_saddr = fl.fld_src;
- rt->rt_daddr = fl.fld_dst;
- rt->rt_gateway = fl.fld_dst;
+ rt->rt_saddr = fld.saddr;
+ rt->rt_daddr = fld.daddr;
+ rt->rt_gateway = fld.daddr;
if (gateway)
rt->rt_gateway = gateway;
rt->rt_local_src = local_src ? local_src : rt->rt_saddr;
- rt->rt_dst_map = fl.fld_dst;
- rt->rt_src_map = fl.fld_src;
+ rt->rt_dst_map = fld.daddr;
+ rt->rt_src_map = fld.saddr;
- rt->fl.fld_src = cb->src;
- rt->fl.fld_dst = cb->dst;
- rt->fl.flowi_oif = 0;
- rt->fl.flowi_iif = in_dev->ifindex;
- rt->fl.flowi_mark = fl.flowi_mark;
+ rt->fld.saddr = cb->src;
+ rt->fld.daddr = cb->dst;
+ rt->fld.flowidn_oif = 0;
+ rt->fld.flowidn_iif = in_dev->ifindex;
+ rt->fld.flowidn_mark = fld.flowidn_mark;
rt->dst.flags = DST_HOST;
rt->dst.neighbour = neigh;
@@ -1444,7 +1447,7 @@ make_route:
if (err)
goto e_neighbour;
- hash = dn_hash(rt->fl.fld_src, rt->fl.fld_dst);
+ hash = dn_hash(rt->fld.saddr, rt->fld.daddr);
dn_insert_route(rt, hash, &rt);
skb_dst_set(skb, &rt->dst);
@@ -1484,11 +1487,11 @@ static int dn_route_input(struct sk_buff *skb)
rcu_read_lock();
for(rt = rcu_dereference(dn_rt_hash_table[hash].chain); rt != NULL;
rt = rcu_dereference(rt->dst.dn_next)) {
- if ((rt->fl.fld_src == cb->src) &&
- (rt->fl.fld_dst == cb->dst) &&
- (rt->fl.flowi_oif == 0) &&
- (rt->fl.flowi_mark == skb->mark) &&
- (rt->fl.flowi_iif == cb->iif)) {
+ if ((rt->fld.saddr == cb->src) &&
+ (rt->fld.daddr == cb->dst) &&
+ (rt->fld.flowidn_oif == 0) &&
+ (rt->fld.flowidn_mark == skb->mark) &&
+ (rt->fld.flowidn_iif == cb->iif)) {
dst_use(&rt->dst, jiffies);
rcu_read_unlock();
skb_dst_set(skb, (struct dst_entry *)rt);
@@ -1524,9 +1527,9 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
if (rt->rt_flags & RTCF_NOTIFY)
r->rtm_flags |= RTM_F_NOTIFY;
RTA_PUT(skb, RTA_DST, 2, &rt->rt_daddr);
- if (rt->fl.fld_src) {
+ if (rt->fld.saddr) {
r->rtm_src_len = 16;
- RTA_PUT(skb, RTA_SRC, 2, &rt->fl.fld_src);
+ RTA_PUT(skb, RTA_SRC, 2, &rt->fld.saddr);
}
if (rt->dst.dev)
RTA_PUT(skb, RTA_OIF, sizeof(int), &rt->dst.dev->ifindex);
@@ -1545,7 +1548,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
rt->dst.error) < 0)
goto rtattr_failure;
if (dn_is_input_route(rt))
- RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.flowi_iif);
+ RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fld.flowidn_iif);
nlh->nlmsg_len = skb_tail_pointer(skb) - b;
return skb->len;
@@ -1568,13 +1571,13 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
struct dn_skb_cb *cb;
int err;
struct sk_buff *skb;
- struct flowi fl;
+ struct flowidn fld;
if (!net_eq(net, &init_net))
return -EINVAL;
- memset(&fl, 0, sizeof(fl));
- fl.flowi_proto = DNPROTO_NSP;
+ memset(&fld, 0, sizeof(fld));
+ fld.flowidn_proto = DNPROTO_NSP;
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
if (skb == NULL)
@@ -1583,15 +1586,15 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
cb = DN_SKB_CB(skb);
if (rta[RTA_SRC-1])
- memcpy(&fl.fld_src, RTA_DATA(rta[RTA_SRC-1]), 2);
+ memcpy(&fld.saddr, RTA_DATA(rta[RTA_SRC-1]), 2);
if (rta[RTA_DST-1])
- memcpy(&fl.fld_dst, RTA_DATA(rta[RTA_DST-1]), 2);
+ memcpy(&fld.daddr, RTA_DATA(rta[RTA_DST-1]), 2);
if (rta[RTA_IIF-1])
- memcpy(&fl.flowi_iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int));
+ memcpy(&fld.flowidn_iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int));
- if (fl.flowi_iif) {
+ if (fld.flowidn_iif) {
struct net_device *dev;
- if ((dev = dev_get_by_index(&init_net, fl.flowi_iif)) == NULL) {
+ if ((dev = dev_get_by_index(&init_net, fld.flowidn_iif)) == NULL) {
kfree_skb(skb);
return -ENODEV;
}
@@ -1602,8 +1605,8 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
}
skb->protocol = htons(ETH_P_DNA_RT);
skb->dev = dev;
- cb->src = fl.fld_src;
- cb->dst = fl.fld_dst;
+ cb->src = fld.saddr;
+ cb->dst = fld.daddr;
local_bh_disable();
err = dn_route_input(skb);
local_bh_enable();
@@ -1615,8 +1618,8 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
int oif = 0;
if (rta[RTA_OIF - 1])
memcpy(&oif, RTA_DATA(rta[RTA_OIF - 1]), sizeof(int));
- fl.flowi_oif = oif;
- err = dn_route_output_key((struct dst_entry **)&rt, &fl, 0);
+ fld.flowidn_oif = oif;
+ err = dn_route_output_key((struct dst_entry **)&rt, &fld, 0);
}
if (skb->dev)
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 6eb91df..f0efb0c 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -49,14 +49,15 @@ struct dn_fib_rule
};
-int dn_fib_lookup(struct flowi *flp, struct dn_fib_res *res)
+int dn_fib_lookup(struct flowidn *flp, struct dn_fib_res *res)
{
struct fib_lookup_arg arg = {
.result = res,
};
int err;
- err = fib_rules_lookup(dn_fib_rules_ops, flp, 0, &arg);
+ err = fib_rules_lookup(dn_fib_rules_ops,
+ flowidn_to_flowi(flp), 0, &arg);
res->r = arg.rule;
return err;
@@ -65,6 +66,7 @@ int dn_fib_lookup(struct flowi *flp, struct dn_fib_res *res)
static int dn_fib_rule_action(struct fib_rule *rule, struct flowi *flp,
int flags, struct fib_lookup_arg *arg)
{
+ struct flowidn *fld = &flp->u.dn;
int err = -EAGAIN;
struct dn_fib_table *tbl;
@@ -90,7 +92,7 @@ static int dn_fib_rule_action(struct fib_rule *rule, struct flowi *flp,
if (tbl == NULL)
goto errout;
- err = tbl->lookup(tbl, flp, (struct dn_fib_res *)arg->result);
+ err = tbl->lookup(tbl, fld, (struct dn_fib_res *)arg->result);
if (err > 0)
err = -EAGAIN;
errout:
@@ -104,8 +106,9 @@ static const struct nla_policy dn_fib_rule_policy[FRA_MAX+1] = {
static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
{
struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
- __le16 daddr = fl->fld_dst;
- __le16 saddr = fl->fld_src;
+ struct flowidn *fld = &fl->u.dn;
+ __le16 daddr = fld->daddr;
+ __le16 saddr = fld->saddr;
if (((saddr ^ r->src) & r->srcmask) ||
((daddr ^ r->dst) & r->dstmask))
@@ -175,7 +178,7 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
unsigned dnet_addr_type(__le16 addr)
{
- struct flowi fl = { .fld_dst = addr };
+ struct flowidn fld = { .daddr = addr };
struct dn_fib_res res;
unsigned ret = RTN_UNICAST;
struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0);
@@ -183,7 +186,7 @@ unsigned dnet_addr_type(__le16 addr)
res.r = NULL;
if (tb) {
- if (!tb->lookup(tb, &fl, &res)) {
+ if (!tb->lookup(tb, &fld, &res)) {
ret = res.type;
dn_fib_res_put(&res);
}
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index b66600b..99d8d3a 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -764,7 +764,7 @@ static int dn_fib_table_flush(struct dn_fib_table *tb)
return found;
}
-static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowi *flp, struct dn_fib_res *res)
+static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowidn *flp, struct dn_fib_res *res)
{
int err;
struct dn_zone *dz;
@@ -773,7 +773,7 @@ static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowi *flp,
read_lock(&dn_fib_tables_lock);
for(dz = t->dh_zone_list; dz; dz = dz->dz_next) {
struct dn_fib_node *f;
- dn_fib_key_t k = dz_key(flp->fld_dst, dz);
+ dn_fib_key_t k = dz_key(flp->daddr, dz);
for(f = dz_chain(k, dz); f; f = f->fn_next) {
if (!dn_key_eq(k, f->fn_key)) {
@@ -788,7 +788,7 @@ static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowi *flp,
if (f->fn_state&DN_S_ZOMBIE)
continue;
- if (f->fn_scope < flp->fld_scope)
+ if (f->fn_scope < flp->flowidn_scope)
continue;
err = dn_fib_semantic_match(f->fn_type, DN_FIB_INFO(f), flp, res);
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 RFC 1/8] ipv4: Delete routing cache.
From: David Miller @ 2011-03-13 0:35 UTC (permalink / raw)
To: netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/route.h | 1 -
net/ipv4/fib_frontend.c | 5 -
net/ipv4/route.c | 908 ++---------------------------------------------
3 files changed, 23 insertions(+), 891 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index 30d6cae..665a44b 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -121,7 +121,6 @@ extern int ip_rt_init(void);
extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32 src, struct net_device *dev);
extern void rt_cache_flush(struct net *net, int how);
-extern void rt_cache_flush_batch(struct net *net);
extern struct rtable *__ip_route_output_key(struct net *, const struct flowi4 *flp);
extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
struct sock *sk);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index a373a25..e7a030a 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -942,11 +942,6 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
rt_cache_flush(dev_net(dev), 0);
break;
case NETDEV_UNREGISTER_BATCH:
- /* The batch unregister is only called on the first
- * device in the list of devices being unregistered.
- * Therefore we should not pass dev_net(dev) in here.
- */
- rt_cache_flush_batch(NULL);
break;
}
return NOTIFY_DONE;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5655095..5528d14 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -129,7 +129,6 @@ static int ip_rt_gc_elasticity __read_mostly = 8;
static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ;
static int ip_rt_min_pmtu __read_mostly = 512 + 20 + 20;
static int ip_rt_min_advmss __read_mostly = 256;
-static int rt_chain_length_max __read_mostly = 20;
/*
* Interface to generic destination cache.
@@ -142,7 +141,6 @@ static void ipv4_dst_destroy(struct dst_entry *dst);
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
static void ipv4_link_failure(struct sk_buff *skb);
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
-static int rt_garbage_collect(struct dst_ops *ops);
static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
int how)
@@ -187,7 +185,6 @@ static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old)
static struct dst_ops ipv4_dst_ops = {
.family = AF_INET,
.protocol = cpu_to_be16(ETH_P_IP),
- .gc = rt_garbage_collect,
.check = ipv4_dst_check,
.default_advmss = ipv4_default_advmss,
.default_mtu = ipv4_default_mtu,
@@ -222,184 +219,30 @@ const __u8 ip_tos2prio[16] = {
};
-/*
- * Route cache.
- */
-
-/* The locking scheme is rather straight forward:
- *
- * 1) Read-Copy Update protects the buckets of the central route hash.
- * 2) Only writers remove entries, and they hold the lock
- * as they look at rtable reference counts.
- * 3) Only readers acquire references to rtable entries,
- * they do so with atomic increments and with the
- * lock held.
- */
-
-struct rt_hash_bucket {
- struct rtable __rcu *chain;
-};
-
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || \
- defined(CONFIG_PROVE_LOCKING)
-/*
- * Instead of using one spinlock for each rt_hash_bucket, we use a table of spinlocks
- * The size of this table is a power of two and depends on the number of CPUS.
- * (on lockdep we have a quite big spinlock_t, so keep the size down there)
- */
-#ifdef CONFIG_LOCKDEP
-# define RT_HASH_LOCK_SZ 256
-#else
-# if NR_CPUS >= 32
-# define RT_HASH_LOCK_SZ 4096
-# elif NR_CPUS >= 16
-# define RT_HASH_LOCK_SZ 2048
-# elif NR_CPUS >= 8
-# define RT_HASH_LOCK_SZ 1024
-# elif NR_CPUS >= 4
-# define RT_HASH_LOCK_SZ 512
-# else
-# define RT_HASH_LOCK_SZ 256
-# endif
-#endif
-
-static spinlock_t *rt_hash_locks;
-# define rt_hash_lock_addr(slot) &rt_hash_locks[(slot) & (RT_HASH_LOCK_SZ - 1)]
-
-static __init void rt_hash_lock_init(void)
-{
- int i;
-
- rt_hash_locks = kmalloc(sizeof(spinlock_t) * RT_HASH_LOCK_SZ,
- GFP_KERNEL);
- if (!rt_hash_locks)
- panic("IP: failed to allocate rt_hash_locks\n");
-
- for (i = 0; i < RT_HASH_LOCK_SZ; i++)
- spin_lock_init(&rt_hash_locks[i]);
-}
-#else
-# define rt_hash_lock_addr(slot) NULL
-
-static inline void rt_hash_lock_init(void)
-{
-}
-#endif
-
-static struct rt_hash_bucket *rt_hash_table __read_mostly;
-static unsigned rt_hash_mask __read_mostly;
-static unsigned int rt_hash_log __read_mostly;
-
static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
#define RT_CACHE_STAT_INC(field) __this_cpu_inc(rt_cache_stat.field)
-static inline unsigned int rt_hash(__be32 daddr, __be32 saddr, int idx,
- int genid)
-{
- return jhash_3words((__force u32)daddr, (__force u32)saddr,
- idx, genid)
- & rt_hash_mask;
-}
-
static inline int rt_genid(struct net *net)
{
return atomic_read(&net->ipv4.rt_genid);
}
#ifdef CONFIG_PROC_FS
-struct rt_cache_iter_state {
- struct seq_net_private p;
- int bucket;
- int genid;
-};
-
-static struct rtable *rt_cache_get_first(struct seq_file *seq)
-{
- struct rt_cache_iter_state *st = seq->private;
- struct rtable *r = NULL;
-
- for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) {
- if (!rcu_dereference_raw(rt_hash_table[st->bucket].chain))
- continue;
- rcu_read_lock_bh();
- r = rcu_dereference_bh(rt_hash_table[st->bucket].chain);
- while (r) {
- if (dev_net(r->dst.dev) == seq_file_net(seq) &&
- r->rt_genid == st->genid)
- return r;
- r = rcu_dereference_bh(r->dst.rt_next);
- }
- rcu_read_unlock_bh();
- }
- return r;
-}
-
-static struct rtable *__rt_cache_get_next(struct seq_file *seq,
- struct rtable *r)
-{
- struct rt_cache_iter_state *st = seq->private;
-
- r = rcu_dereference_bh(r->dst.rt_next);
- while (!r) {
- rcu_read_unlock_bh();
- do {
- if (--st->bucket < 0)
- return NULL;
- } while (!rcu_dereference_raw(rt_hash_table[st->bucket].chain));
- rcu_read_lock_bh();
- r = rcu_dereference_bh(rt_hash_table[st->bucket].chain);
- }
- return r;
-}
-
-static struct rtable *rt_cache_get_next(struct seq_file *seq,
- struct rtable *r)
-{
- struct rt_cache_iter_state *st = seq->private;
- while ((r = __rt_cache_get_next(seq, r)) != NULL) {
- if (dev_net(r->dst.dev) != seq_file_net(seq))
- continue;
- if (r->rt_genid == st->genid)
- break;
- }
- return r;
-}
-
-static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos)
-{
- struct rtable *r = rt_cache_get_first(seq);
-
- if (r)
- while (pos && (r = rt_cache_get_next(seq, r)))
- --pos;
- return pos ? NULL : r;
-}
-
static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
{
- struct rt_cache_iter_state *st = seq->private;
if (*pos)
- return rt_cache_get_idx(seq, *pos - 1);
- st->genid = rt_genid(seq_file_net(seq));
+ return NULL;
return SEQ_START_TOKEN;
}
static void *rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct rtable *r;
-
- if (v == SEQ_START_TOKEN)
- r = rt_cache_get_first(seq);
- else
- r = rt_cache_get_next(seq, v);
++*pos;
- return r;
+ return NULL;
}
static void rt_cache_seq_stop(struct seq_file *seq, void *v)
{
- if (v && v != SEQ_START_TOKEN)
- rcu_read_unlock_bh();
}
static int rt_cache_seq_show(struct seq_file *seq, void *v)
@@ -409,29 +252,6 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
"Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t"
"Metric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\t"
"HHUptod\tSpecDst");
- else {
- struct rtable *r = v;
- int len;
-
- seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t"
- "%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n",
- r->dst.dev ? r->dst.dev->name : "*",
- (__force u32)r->rt_dst,
- (__force u32)r->rt_gateway,
- r->rt_flags, atomic_read(&r->dst.__refcnt),
- r->dst.__use, 0, (__force u32)r->rt_src,
- dst_metric_advmss(&r->dst) + 40,
- dst_metric(&r->dst, RTAX_WINDOW),
- (int)((dst_metric(&r->dst, RTAX_RTT) >> 3) +
- dst_metric(&r->dst, RTAX_RTTVAR)),
- r->rt_tos,
- r->dst.hh ? atomic_read(&r->dst.hh->hh_refcnt) : -1,
- r->dst.hh ? (r->dst.hh->hh_output ==
- dev_queue_xmit) : 0,
- r->rt_spec_dst, &len);
-
- seq_printf(seq, "%*s\n", 127 - len, "");
- }
return 0;
}
@@ -444,8 +264,7 @@ static const struct seq_operations rt_cache_seq_ops = {
static int rt_cache_seq_open(struct inode *inode, struct file *file)
{
- return seq_open_net(inode, file, &rt_cache_seq_ops,
- sizeof(struct rt_cache_iter_state));
+ return seq_open(file, &rt_cache_seq_ops);
}
static const struct file_operations rt_cache_seq_fops = {
@@ -453,7 +272,7 @@ static const struct file_operations rt_cache_seq_fops = {
.open = rt_cache_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release_net,
+ .release = seq_release,
};
@@ -643,184 +462,12 @@ static inline int ip_rt_proc_init(void)
}
#endif /* CONFIG_PROC_FS */
-static inline void rt_free(struct rtable *rt)
-{
- call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
-}
-
-static inline void rt_drop(struct rtable *rt)
-{
- ip_rt_put(rt);
- call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
-}
-
-static inline int rt_fast_clean(struct rtable *rth)
-{
- /* Kill broadcast/multicast entries very aggresively, if they
- collide in hash table with more useful entries */
- return (rth->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) &&
- rt_is_input_route(rth) && rth->dst.rt_next;
-}
-
-static inline int rt_valuable(struct rtable *rth)
-{
- return (rth->rt_flags & (RTCF_REDIRECTED | RTCF_NOTIFY)) ||
- (rth->peer && rth->peer->pmtu_expires);
-}
-
-static int rt_may_expire(struct rtable *rth, unsigned long tmo1, unsigned long tmo2)
-{
- unsigned long age;
- int ret = 0;
-
- if (atomic_read(&rth->dst.__refcnt))
- goto out;
-
- age = jiffies - rth->dst.lastuse;
- if ((age <= tmo1 && !rt_fast_clean(rth)) ||
- (age <= tmo2 && rt_valuable(rth)))
- goto out;
- ret = 1;
-out: return ret;
-}
-
-/* Bits of score are:
- * 31: very valuable
- * 30: not quite useless
- * 29..0: usage counter
- */
-static inline u32 rt_score(struct rtable *rt)
-{
- u32 score = jiffies - rt->dst.lastuse;
-
- score = ~score & ~(3<<30);
-
- if (rt_valuable(rt))
- score |= (1<<31);
-
- if (rt_is_output_route(rt) ||
- !(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL)))
- score |= (1<<30);
-
- return score;
-}
-
-static inline bool rt_caching(const struct net *net)
-{
- return net->ipv4.current_rt_cache_rebuild_count <=
- net->ipv4.sysctl_rt_cache_rebuild_count;
-}
-
-static inline bool compare_hash_inputs(const struct rtable *rt1,
- const struct rtable *rt2)
-{
- return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) |
- ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) |
- (rt1->rt_iif ^ rt2->rt_iif)) == 0);
-}
-
-static inline int compare_keys(struct rtable *rt1, struct rtable *rt2)
-{
- return (((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) |
- ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) |
- (rt1->rt_mark ^ rt2->rt_mark) |
- (rt1->rt_tos ^ rt2->rt_tos) |
- (rt1->rt_oif ^ rt2->rt_oif) |
- (rt1->rt_iif ^ rt2->rt_iif)) == 0;
-}
-
-static inline int compare_netns(struct rtable *rt1, struct rtable *rt2)
-{
- return net_eq(dev_net(rt1->dst.dev), dev_net(rt2->dst.dev));
-}
-
static inline int rt_is_expired(struct rtable *rth)
{
return rth->rt_genid != rt_genid(dev_net(rth->dst.dev));
}
/*
- * Perform a full scan of hash table and free all entries.
- * Can be called by a softirq or a process.
- * In the later case, we want to be reschedule if necessary
- */
-static void rt_do_flush(struct net *net, int process_context)
-{
- unsigned int i;
- struct rtable *rth, *next;
-
- for (i = 0; i <= rt_hash_mask; i++) {
- struct rtable __rcu **pprev;
- struct rtable *list;
-
- if (process_context && need_resched())
- cond_resched();
- rth = rcu_dereference_raw(rt_hash_table[i].chain);
- if (!rth)
- continue;
-
- spin_lock_bh(rt_hash_lock_addr(i));
-
- list = NULL;
- pprev = &rt_hash_table[i].chain;
- rth = rcu_dereference_protected(*pprev,
- lockdep_is_held(rt_hash_lock_addr(i)));
-
- while (rth) {
- next = rcu_dereference_protected(rth->dst.rt_next,
- lockdep_is_held(rt_hash_lock_addr(i)));
-
- if (!net ||
- net_eq(dev_net(rth->dst.dev), net)) {
- rcu_assign_pointer(*pprev, next);
- rcu_assign_pointer(rth->dst.rt_next, list);
- list = rth;
- } else {
- pprev = &rth->dst.rt_next;
- }
- rth = next;
- }
-
- spin_unlock_bh(rt_hash_lock_addr(i));
-
- for (; list; list = next) {
- next = rcu_dereference_protected(list->dst.rt_next, 1);
- rt_free(list);
- }
- }
-}
-
-/*
- * While freeing expired entries, we compute average chain length
- * and standard deviation, using fixed-point arithmetic.
- * This to have an estimation of rt_chain_length_max
- * rt_chain_length_max = max(elasticity, AVG + 4*SD)
- * We use 3 bits for frational part, and 29 (or 61) for magnitude.
- */
-
-#define FRACT_BITS 3
-#define ONE (1UL << FRACT_BITS)
-
-/*
- * Given a hash chain and an item in this hash chain,
- * find if a previous entry has the same hash_inputs
- * (but differs on tos, mark or oif)
- * Returns 0 if an alias is found.
- * Returns ONE if rth has no alias before itself.
- */
-static int has_noalias(const struct rtable *head, const struct rtable *rth)
-{
- const struct rtable *aux = head;
-
- while (aux != rth) {
- if (compare_hash_inputs(aux, rth))
- return 0;
- aux = rcu_dereference_protected(aux->dst.rt_next, 1);
- }
- return ONE;
-}
-
-/*
* Pertubation of rt_genid by a small quantity [1..256]
* Using 8 bits of shuffling ensure we can call rt_cache_invalidate()
* many times (2^24) without giving recent rt_genid.
@@ -841,364 +488,25 @@ static void rt_cache_invalidate(struct net *net)
void rt_cache_flush(struct net *net, int delay)
{
rt_cache_invalidate(net);
- if (delay >= 0)
- rt_do_flush(net, !in_softirq());
}
-/* Flush previous cache invalidated entries from the cache */
-void rt_cache_flush_batch(struct net *net)
+static struct rtable *rt_finalize(struct rtable *rt, struct sk_buff *skb)
{
- rt_do_flush(net, !in_softirq());
-}
-
-static void rt_emergency_hash_rebuild(struct net *net)
-{
- if (net_ratelimit())
- printk(KERN_WARNING "Route hash chain too long!\n");
- rt_cache_invalidate(net);
-}
-
-/*
- Short description of GC goals.
-
- We want to build algorithm, which will keep routing cache
- at some equilibrium point, when number of aged off entries
- is kept approximately equal to newly generated ones.
-
- Current expiration strength is variable "expire".
- We try to adjust it dynamically, so that if networking
- is idle expires is large enough to keep enough of warm entries,
- and when load increases it reduces to limit cache size.
- */
-
-static int rt_garbage_collect(struct dst_ops *ops)
-{
- static unsigned long expire = RT_GC_TIMEOUT;
- static unsigned long last_gc;
- static int rover;
- static int equilibrium;
- struct rtable *rth;
- struct rtable __rcu **rthp;
- unsigned long now = jiffies;
- int goal;
- int entries = dst_entries_get_fast(&ipv4_dst_ops);
-
- /*
- * Garbage collection is pretty expensive,
- * do not make it too frequently.
- */
-
- RT_CACHE_STAT_INC(gc_total);
-
- if (now - last_gc < ip_rt_gc_min_interval &&
- entries < ip_rt_max_size) {
- RT_CACHE_STAT_INC(gc_ignored);
- goto out;
- }
-
- entries = dst_entries_get_slow(&ipv4_dst_ops);
- /* Calculate number of entries, which we want to expire now. */
- goal = entries - (ip_rt_gc_elasticity << rt_hash_log);
- if (goal <= 0) {
- if (equilibrium < ipv4_dst_ops.gc_thresh)
- equilibrium = ipv4_dst_ops.gc_thresh;
- goal = entries - equilibrium;
- if (goal > 0) {
- equilibrium += min_t(unsigned int, goal >> 1, rt_hash_mask + 1);
- goal = entries - equilibrium;
- }
- } else {
- /* We are in dangerous area. Try to reduce cache really
- * aggressively.
- */
- goal = max_t(unsigned int, goal >> 1, rt_hash_mask + 1);
- equilibrium = entries - goal;
- }
-
- if (now - last_gc >= ip_rt_gc_min_interval)
- last_gc = now;
-
- if (goal <= 0) {
- equilibrium += goal;
- goto work_done;
- }
-
- do {
- int i, k;
-
- for (i = rt_hash_mask, k = rover; i >= 0; i--) {
- unsigned long tmo = expire;
-
- k = (k + 1) & rt_hash_mask;
- rthp = &rt_hash_table[k].chain;
- spin_lock_bh(rt_hash_lock_addr(k));
- while ((rth = rcu_dereference_protected(*rthp,
- lockdep_is_held(rt_hash_lock_addr(k)))) != NULL) {
- if (!rt_is_expired(rth) &&
- !rt_may_expire(rth, tmo, expire)) {
- tmo >>= 1;
- rthp = &rth->dst.rt_next;
- continue;
- }
- *rthp = rth->dst.rt_next;
- rt_free(rth);
- goal--;
- }
- spin_unlock_bh(rt_hash_lock_addr(k));
- if (goal <= 0)
- break;
- }
- rover = k;
-
- if (goal <= 0)
- goto work_done;
-
- /* Goal is not achieved. We stop process if:
-
- - if expire reduced to zero. Otherwise, expire is halfed.
- - if table is not full.
- - if we are called from interrupt.
- - jiffies check is just fallback/debug loop breaker.
- We will not spin here for long time in any case.
- */
-
- RT_CACHE_STAT_INC(gc_goal_miss);
-
- if (expire == 0)
- break;
-
- expire >>= 1;
-#if RT_CACHE_DEBUG >= 2
- printk(KERN_DEBUG "expire>> %u %d %d %d\n", expire,
- dst_entries_get_fast(&ipv4_dst_ops), goal, i);
-#endif
-
- if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size)
- goto out;
- } while (!in_softirq() && time_before_eq(jiffies, now));
-
- if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size)
- goto out;
- if (dst_entries_get_slow(&ipv4_dst_ops) < ip_rt_max_size)
- goto out;
- if (net_ratelimit())
- printk(KERN_WARNING "dst cache overflow\n");
- RT_CACHE_STAT_INC(gc_dst_overflow);
- return 1;
-
-work_done:
- expire += ip_rt_gc_min_interval;
- if (expire > ip_rt_gc_timeout ||
- dst_entries_get_fast(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh ||
- dst_entries_get_slow(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh)
- expire = ip_rt_gc_timeout;
-#if RT_CACHE_DEBUG >= 2
- printk(KERN_DEBUG "expire++ %u %d %d %d\n", expire,
- dst_entries_get_fast(&ipv4_dst_ops), goal, rover);
-#endif
-out: return 0;
-}
-
-/*
- * Returns number of entries in a hash chain that have different hash_inputs
- */
-static int slow_chain_length(const struct rtable *head)
-{
- int length = 0;
- const struct rtable *rth = head;
-
- while (rth) {
- length += has_noalias(head, rth);
- rth = rcu_dereference_protected(rth->dst.rt_next, 1);
- }
- return length >> FRACT_BITS;
-}
-
-static struct rtable *rt_intern_hash(unsigned hash, struct rtable *rt,
- struct sk_buff *skb, int ifindex)
-{
- struct rtable *rth, *cand;
- struct rtable __rcu **rthp, **candp;
- unsigned long now;
- u32 min_score;
- int chain_length;
- int attempts = !in_softirq();
-
-restart:
- chain_length = 0;
- min_score = ~(u32)0;
- cand = NULL;
- candp = NULL;
- now = jiffies;
-
- if (!rt_caching(dev_net(rt->dst.dev))) {
- /*
- * If we're not caching, just tell the caller we
- * were successful and don't touch the route. The
- * caller hold the sole reference to the cache entry, and
- * it will be released when the caller is done with it.
- * If we drop it here, the callers have no way to resolve routes
- * when we're not caching. Instead, just point *rp at rt, so
- * the caller gets a single use out of the route
- * Note that we do rt_free on this new route entry, so that
- * once its refcount hits zero, we are still able to reap it
- * (Thanks Alexey)
- * Note: To avoid expensive rcu stuff for this uncached dst,
- * we set DST_NOCACHE so that dst_release() can free dst without
- * waiting a grace period.
- */
-
- rt->dst.flags |= DST_NOCACHE;
- if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) {
- int err = arp_bind_neighbour(&rt->dst);
- if (err) {
- if (net_ratelimit())
- printk(KERN_WARNING
- "Neighbour table failure & not caching routes.\n");
- ip_rt_put(rt);
- return ERR_PTR(err);
- }
- }
-
- goto skip_hashing;
- }
-
- rthp = &rt_hash_table[hash].chain;
-
- spin_lock_bh(rt_hash_lock_addr(hash));
- while ((rth = rcu_dereference_protected(*rthp,
- lockdep_is_held(rt_hash_lock_addr(hash)))) != NULL) {
- if (rt_is_expired(rth)) {
- *rthp = rth->dst.rt_next;
- rt_free(rth);
- continue;
- }
- if (compare_keys(rth, rt) && compare_netns(rth, rt)) {
- /* Put it first */
- *rthp = rth->dst.rt_next;
- /*
- * Since lookup is lockfree, the deletion
- * must be visible to another weakly ordered CPU before
- * the insertion at the start of the hash chain.
- */
- rcu_assign_pointer(rth->dst.rt_next,
- rt_hash_table[hash].chain);
- /*
- * Since lookup is lockfree, the update writes
- * must be ordered for consistency on SMP.
- */
- rcu_assign_pointer(rt_hash_table[hash].chain, rth);
-
- dst_use(&rth->dst, now);
- spin_unlock_bh(rt_hash_lock_addr(hash));
-
- rt_drop(rt);
- if (skb)
- skb_dst_set(skb, &rth->dst);
- return rth;
- }
-
- if (!atomic_read(&rth->dst.__refcnt)) {
- u32 score = rt_score(rth);
-
- if (score <= min_score) {
- cand = rth;
- candp = rthp;
- min_score = score;
- }
- }
-
- chain_length++;
-
- rthp = &rth->dst.rt_next;
- }
-
- if (cand) {
- /* ip_rt_gc_elasticity used to be average length of chain
- * length, when exceeded gc becomes really aggressive.
- *
- * The second limit is less certain. At the moment it allows
- * only 2 entries per bucket. We will see.
- */
- if (chain_length > ip_rt_gc_elasticity) {
- *candp = cand->dst.rt_next;
- rt_free(cand);
- }
- } else {
- if (chain_length > rt_chain_length_max &&
- slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) {
- struct net *net = dev_net(rt->dst.dev);
- int num = ++net->ipv4.current_rt_cache_rebuild_count;
- if (!rt_caching(net)) {
- printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n",
- rt->dst.dev->name, num);
- }
- rt_emergency_hash_rebuild(net);
- spin_unlock_bh(rt_hash_lock_addr(hash));
-
- hash = rt_hash(rt->rt_key_dst, rt->rt_key_src,
- ifindex, rt_genid(net));
- goto restart;
- }
- }
-
- /* Try to bind route to arp only if it is output
- route or unicast forwarding path.
+ /* To avoid expensive rcu stuff for this uncached dst, we set
+ * DST_NOCACHE so that dst_release() can free dst without
+ * waiting a grace period.
*/
+ rt->dst.flags |= DST_NOCACHE;
if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) {
int err = arp_bind_neighbour(&rt->dst);
if (err) {
- spin_unlock_bh(rt_hash_lock_addr(hash));
-
- if (err != -ENOBUFS) {
- rt_drop(rt);
- return ERR_PTR(err);
- }
-
- /* Neighbour tables are full and nothing
- can be released. Try to shrink route cache,
- it is most likely it holds some neighbour records.
- */
- if (attempts-- > 0) {
- int saved_elasticity = ip_rt_gc_elasticity;
- int saved_int = ip_rt_gc_min_interval;
- ip_rt_gc_elasticity = 1;
- ip_rt_gc_min_interval = 0;
- rt_garbage_collect(&ipv4_dst_ops);
- ip_rt_gc_min_interval = saved_int;
- ip_rt_gc_elasticity = saved_elasticity;
- goto restart;
- }
-
if (net_ratelimit())
- printk(KERN_WARNING "ipv4: Neighbour table overflow.\n");
- rt_drop(rt);
- return ERR_PTR(-ENOBUFS);
+ printk(KERN_WARNING
+ "Neighbour table failure & not caching routes.\n");
+ ip_rt_put(rt);
+ return ERR_PTR(err);
}
}
-
- rt->dst.rt_next = rt_hash_table[hash].chain;
-
-#if RT_CACHE_DEBUG >= 2
- if (rt->dst.rt_next) {
- struct rtable *trt;
- printk(KERN_DEBUG "rt_cache @%02x: %pI4",
- hash, &rt->rt_dst);
- for (trt = rt->dst.rt_next; trt; trt = trt->dst.rt_next)
- printk(" . %pI4", &trt->rt_dst);
- printk("\n");
- }
-#endif
- /*
- * Since lookup is lockfree, we must make sure
- * previous writes to rt are comitted to memory
- * before making rt visible to other CPUS.
- */
- rcu_assign_pointer(rt_hash_table[hash].chain, rt);
-
- spin_unlock_bh(rt_hash_lock_addr(hash));
-
-skip_hashing:
if (skb)
skb_dst_set(skb, &rt->dst);
return rt;
@@ -1266,26 +574,6 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more)
}
EXPORT_SYMBOL(__ip_select_ident);
-static void rt_del(unsigned hash, struct rtable *rt)
-{
- struct rtable __rcu **rthp;
- struct rtable *aux;
-
- rthp = &rt_hash_table[hash].chain;
- spin_lock_bh(rt_hash_lock_addr(hash));
- ip_rt_put(rt);
- while ((aux = rcu_dereference_protected(*rthp,
- lockdep_is_held(rt_hash_lock_addr(hash)))) != NULL) {
- if (aux == rt || rt_is_expired(aux)) {
- *rthp = aux->dst.rt_next;
- rt_free(aux);
- continue;
- }
- rthp = &aux->dst.rt_next;
- }
- spin_unlock_bh(rt_hash_lock_addr(hash));
-}
-
/* called in rcu_read_lock() section */
void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
__be32 saddr, struct net_device *dev)
@@ -1344,14 +632,11 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
ip_rt_put(rt);
ret = NULL;
} else if (rt->rt_flags & RTCF_REDIRECTED) {
- unsigned hash = rt_hash(rt->rt_key_dst, rt->rt_key_src,
- rt->rt_oif,
- rt_genid(dev_net(dst->dev)));
#if RT_CACHE_DEBUG >= 1
printk(KERN_DEBUG "ipv4_negative_advice: redirect to %pI4/%02x dropped\n",
- &rt->rt_dst, rt->rt_tos);
+ &rt->rt_dst, rt->rt_tos);
#endif
- rt_del(hash, rt);
+ ip_rt_put(rt);
ret = NULL;
} else if (rt->peer &&
rt->peer->pmtu_expires &&
@@ -1840,7 +1125,6 @@ static struct rtable *rt_dst_alloc(bool nopolicy, bool noxfrm)
static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev, int our)
{
- unsigned int hash;
struct rtable *rth;
__be32 spec_dst;
struct in_device *in_dev = __in_dev_get_rcu(dev);
@@ -1901,8 +1185,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
#endif
RT_CACHE_STAT_INC(in_slow_mc);
- hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
- rth = rt_intern_hash(hash, rth, skb, dev->ifindex);
+ rth = rt_finalize(rth, skb);
err = 0;
if (IS_ERR(rth))
err = PTR_ERR(rth);
@@ -2044,7 +1327,6 @@ static int ip_mkroute_input(struct sk_buff *skb,
{
struct rtable* rth = NULL;
int err;
- unsigned hash;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
if (res->fi && res->fi->fib_nhs > 1)
@@ -2056,10 +1338,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
if (err)
return err;
- /* put it into the cache */
- hash = rt_hash(daddr, saddr, fl4->flowi4_iif,
- rt_genid(dev_net(rth->dst.dev)));
- rth = rt_intern_hash(hash, rth, skb, fl4->flowi4_iif);
+ rth = rt_finalize(rth, skb);
if (IS_ERR(rth))
return PTR_ERR(rth);
return 0;
@@ -2085,7 +1364,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
unsigned flags = 0;
u32 itag = 0;
struct rtable * rth;
- unsigned hash;
__be32 spec_dst;
int err = -EINVAL;
struct net * net = dev_net(dev);
@@ -2205,8 +1483,7 @@ local_input:
rth->rt_flags &= ~RTCF_LOCAL;
}
rth->rt_type = res.type;
- hash = rt_hash(daddr, saddr, fl4.flowi4_iif, rt_genid(net));
- rth = rt_intern_hash(hash, rth, skb, fl4.flowi4_iif);
+ rth = rt_finalize(rth, skb);
err = 0;
if (IS_ERR(rth))
err = PTR_ERR(rth);
@@ -2253,47 +1530,10 @@ martian_source_keep_err:
int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev, bool noref)
{
- struct rtable * rth;
- unsigned hash;
- int iif = dev->ifindex;
- struct net *net;
int res;
- net = dev_net(dev);
-
rcu_read_lock();
- if (!rt_caching(net))
- goto skip_cache;
-
- tos &= IPTOS_RT_MASK;
- hash = rt_hash(daddr, saddr, iif, rt_genid(net));
-
- for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
- rth = rcu_dereference(rth->dst.rt_next)) {
- if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) |
- ((__force u32)rth->rt_key_src ^ (__force u32)saddr) |
- (rth->rt_iif ^ iif) |
- rth->rt_oif |
- (rth->rt_tos ^ tos)) == 0 &&
- rth->rt_mark == skb->mark &&
- net_eq(dev_net(rth->dst.dev), net) &&
- !rt_is_expired(rth)) {
- if (noref) {
- dst_use_noref(&rth->dst, jiffies);
- skb_dst_set_noref(skb, &rth->dst);
- } else {
- dst_use(&rth->dst, jiffies);
- skb_dst_set(skb, &rth->dst);
- }
- RT_CACHE_STAT_INC(in_hit);
- rcu_read_unlock();
- return 0;
- }
- RT_CACHE_STAT_INC(in_hlist_search);
- }
-
-skip_cache:
/* Multicast recognition logic is moved from route cache to here.
The problem was that too many Ethernet cards have broken/missing
hardware multicast filters :-( As result the host on multicasting
@@ -2434,11 +1674,9 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
/*
* Major route resolver routine.
- * called with rcu_read_lock();
*/
-static struct rtable *ip_route_output_slow(struct net *net,
- const struct flowi4 *oldflp4)
+struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldflp4)
{
u32 tos = RT_FL_TOS(oldflp4);
struct flowi4 fl4;
@@ -2613,53 +1851,13 @@ static struct rtable *ip_route_output_slow(struct net *net,
make_route:
rth = __mkroute_output(&res, &fl4, oldflp4, dev_out, flags);
- if (!IS_ERR(rth)) {
- unsigned int hash;
-
- hash = rt_hash(oldflp4->daddr, oldflp4->saddr, oldflp4->flowi4_oif,
- rt_genid(dev_net(dev_out)));
- rth = rt_intern_hash(hash, rth, NULL, oldflp4->flowi4_oif);
- }
+ if (!IS_ERR(rth))
+ rth = rt_finalize(rth, NULL);
out:
rcu_read_unlock();
return rth;
}
-
-struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *flp4)
-{
- struct rtable *rth;
- unsigned int hash;
-
- if (!rt_caching(net))
- goto slow_output;
-
- hash = rt_hash(flp4->daddr, flp4->saddr, flp4->flowi4_oif, rt_genid(net));
-
- rcu_read_lock_bh();
- for (rth = rcu_dereference_bh(rt_hash_table[hash].chain); rth;
- rth = rcu_dereference_bh(rth->dst.rt_next)) {
- if (rth->rt_key_dst == flp4->daddr &&
- rth->rt_key_src == flp4->saddr &&
- rt_is_output_route(rth) &&
- rth->rt_oif == flp4->flowi4_oif &&
- rth->rt_mark == flp4->flowi4_mark &&
- !((rth->rt_tos ^ flp4->flowi4_tos) &
- (IPTOS_RT_MASK | RTO_ONLINK)) &&
- net_eq(dev_net(rth->dst.dev), net) &&
- !rt_is_expired(rth)) {
- dst_use(&rth->dst, jiffies);
- RT_CACHE_STAT_INC(out_hit);
- rcu_read_unlock_bh();
- return rth;
- }
- RT_CACHE_STAT_INC(out_hlist_search);
- }
- rcu_read_unlock_bh();
-
-slow_output:
- return ip_route_output_slow(net, flp4);
-}
EXPORT_SYMBOL_GPL(__ip_route_output_key);
static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 cookie)
@@ -2952,43 +2150,6 @@ errout_free:
int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
- struct rtable *rt;
- int h, s_h;
- int idx, s_idx;
- struct net *net;
-
- net = sock_net(skb->sk);
-
- s_h = cb->args[0];
- if (s_h < 0)
- s_h = 0;
- s_idx = idx = cb->args[1];
- for (h = s_h; h <= rt_hash_mask; h++, s_idx = 0) {
- if (!rt_hash_table[h].chain)
- continue;
- rcu_read_lock_bh();
- for (rt = rcu_dereference_bh(rt_hash_table[h].chain), idx = 0; rt;
- rt = rcu_dereference_bh(rt->dst.rt_next), idx++) {
- if (!net_eq(dev_net(rt->dst.dev), net) || idx < s_idx)
- continue;
- if (rt_is_expired(rt))
- continue;
- skb_dst_set_noref(skb, &rt->dst);
- if (rt_fill_info(net, skb, NETLINK_CB(cb->skb).pid,
- cb->nlh->nlmsg_seq, RTM_NEWROUTE,
- 1, NLM_F_MULTI) <= 0) {
- skb_dst_drop(skb);
- rcu_read_unlock_bh();
- goto done;
- }
- skb_dst_drop(skb);
- }
- rcu_read_unlock_bh();
- }
-
-done:
- cb->args[0] = h;
- cb->args[1] = idx;
return skb->len;
}
@@ -3221,16 +2382,6 @@ static __net_initdata struct pernet_operations rt_genid_ops = {
struct ip_rt_acct __percpu *ip_rt_acct __read_mostly;
#endif /* CONFIG_IP_ROUTE_CLASSID */
-static __initdata unsigned long rhash_entries;
-static int __init set_rhash_entries(char *str)
-{
- if (!str)
- return 0;
- rhash_entries = simple_strtoul(str, &str, 0);
- return 1;
-}
-__setup("rhash_entries=", set_rhash_entries);
-
int __init ip_rt_init(void)
{
int rc = 0;
@@ -3253,21 +2404,8 @@ int __init ip_rt_init(void)
if (dst_entries_init(&ipv4_dst_blackhole_ops) < 0)
panic("IP: failed to allocate ipv4_dst_blackhole_ops counter\n");
- rt_hash_table = (struct rt_hash_bucket *)
- alloc_large_system_hash("IP route cache",
- sizeof(struct rt_hash_bucket),
- rhash_entries,
- (totalram_pages >= 128 * 1024) ?
- 15 : 17,
- 0,
- &rt_hash_log,
- &rt_hash_mask,
- rhash_entries ? 0 : 512 * 1024);
- memset(rt_hash_table, 0, (rt_hash_mask + 1) * sizeof(struct rt_hash_bucket));
- rt_hash_lock_init();
-
- ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1);
- ip_rt_max_size = (rt_hash_mask + 1) * 16;
+ ipv4_dst_ops.gc_thresh = ~0;
+ ip_rt_max_size = INT_MAX;
devinet_init();
ip_fib_init();
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 RFC 2/8] ipv4: Kill ip_route_input_noref().
From: David Miller @ 2011-03-13 0:35 UTC (permalink / raw)
To: netdev
The "noref" argument to ip_route_input_common() is now always ignored
because we do not cache routes, and in that case we must always grab
a reference to the resulting 'dst'.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/route.h | 16 ++--------------
net/ipv4/arp.c | 2 +-
net/ipv4/ip_input.c | 4 ++--
net/ipv4/route.c | 6 +++---
net/ipv4/xfrm4_input.c | 4 ++--
5 files changed, 10 insertions(+), 22 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index 665a44b..78e8ce1 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -179,20 +179,8 @@ static inline struct rtable *ip_route_output_gre(struct net *net,
return ip_route_output_key(net, &fl4);
}
-extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
- u8 tos, struct net_device *devin, bool noref);
-
-static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
- u8 tos, struct net_device *devin)
-{
- return ip_route_input_common(skb, dst, src, tos, devin, false);
-}
-
-static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src,
- u8 tos, struct net_device *devin)
-{
- return ip_route_input_common(skb, dst, src, tos, devin, true);
-}
+extern int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
+ u8 tos, struct net_device *devin);
extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev);
extern void ip_rt_send_redirect(struct sk_buff *skb);
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 090d273..db0b8b8 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -872,7 +872,7 @@ static int arp_process(struct sk_buff *skb)
}
if (arp->ar_op == htons(ARPOP_REQUEST) &&
- ip_route_input_noref(skb, tip, sip, 0, dev) == 0) {
+ ip_route_input(skb, tip, sip, 0, dev) == 0) {
rt = skb_rtable(skb);
addr_type = rt->rt_type;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index d7b2b09..577eb45 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -324,8 +324,8 @@ static int ip_rcv_finish(struct sk_buff *skb)
* how the packet travels inside Linux networking.
*/
if (skb_dst(skb) == NULL) {
- int err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
- iph->tos, skb->dev);
+ int err = ip_route_input(skb, iph->daddr, iph->saddr,
+ iph->tos, skb->dev);
if (unlikely(err)) {
if (err == -EHOSTUNREACH)
IP_INC_STATS_BH(dev_net(skb->dev),
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5528d14..7e8720f 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1527,8 +1527,8 @@ martian_source_keep_err:
goto out;
}
-int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
- u8 tos, struct net_device *dev, bool noref)
+int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
+ u8 tos, struct net_device *dev)
{
int res;
@@ -1571,7 +1571,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rcu_read_unlock();
return res;
}
-EXPORT_SYMBOL(ip_route_input_common);
+EXPORT_SYMBOL(ip_route_input);
/* called with rcu_read_lock() */
static struct rtable *__mkroute_output(const struct fib_result *res,
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 06814b6..58d23a5 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -27,8 +27,8 @@ static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
if (skb_dst(skb) == NULL) {
const struct iphdr *iph = ip_hdr(skb);
- if (ip_route_input_noref(skb, iph->daddr, iph->saddr,
- iph->tos, skb->dev))
+ if (ip_route_input(skb, iph->daddr, iph->saddr,
+ iph->tos, skb->dev))
goto drop;
}
return dst_input(skb);
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 RFC 3/8] ipv4: Set DST_NOCACHE in rt_dst_alloc().
From: David Miller @ 2011-03-13 0:36 UTC (permalink / raw)
To: netdev
Instead of using a read/modify/write in rt_finalize().
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv4/route.c | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 7e8720f..6036476 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -492,11 +492,6 @@ void rt_cache_flush(struct net *net, int delay)
static struct rtable *rt_finalize(struct rtable *rt, struct sk_buff *skb)
{
- /* To avoid expensive rcu stuff for this uncached dst, we set
- * DST_NOCACHE so that dst_release() can free dst without
- * waiting a grace period.
- */
- rt->dst.flags |= DST_NOCACHE;
if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) {
int err = arp_bind_neighbour(&rt->dst);
if (err) {
@@ -1114,7 +1109,11 @@ static struct rtable *rt_dst_alloc(bool nopolicy, bool noxfrm)
if (rt) {
rt->dst.obsolete = -1;
- rt->dst.flags = DST_HOST |
+ /* To avoid expensive rcu stuff for this uncached dst, we set
+ * DST_NOCACHE so that dst_release() can free dst without
+ * waiting a grace period.
+ */
+ rt->dst.flags = DST_NOCACHE | DST_HOST |
(nopolicy ? DST_NOPOLICY : 0) |
(noxfrm ? DST_NOXFRM : 0);
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 RFC 4/8] netlink: Add NLM_F_NOREPLY flags.
From: David Miller @ 2011-03-13 0:36 UTC (permalink / raw)
To: netdev
It is used to bypass the response generation for "GET" type
operations.
This mechanism can then be used to allow a query operation to be used
in a "benchmarking" role, since the actual overhead of the netlink
communications will be muted.
The first query to support this is inet_rtm_getroute().
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/linux/netlink.h | 2 ++
net/ipv4/route.c | 3 +++
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 4c4ac3f..a63c0e5 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -61,6 +61,8 @@ struct nlmsghdr {
#define NLM_F_CREATE 0x400 /* Create, if it does not exist */
#define NLM_F_APPEND 0x800 /* Add to end of list */
+#define NLM_F_NOREPLY 0x1000 /* Do not generate reply */
+
/*
4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL
4.4BSD CHANGE NLM_F_REPLACE
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 6036476..96dd498 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2130,6 +2130,9 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
goto errout_free;
skb_dst_set(skb, &rt->dst);
+ if (nlh->nlmsg_flags & NLM_F_NOREPLY)
+ goto errout_free;
+
if (rtm->rtm_flags & RTM_F_NOTIFY)
rt->rt_flags |= RTCF_NOTIFY;
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 RFC 5/8] net: Make dst_alloc() take more explicit initializations.
From: David Miller @ 2011-03-13 0:37 UTC (permalink / raw)
To: netdev
Now the dst->dev, dev->obsolete, and dst->flags values can
be specified as well.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/dst.h | 3 ++-
net/core/dst.c | 18 +++++++++++++-----
net/decnet/dn_route.c | 13 ++-----------
net/ipv4/route.c | 48 +++++++++++++++++++-----------------------------
net/ipv6/route.c | 29 +++++++++++------------------
net/xfrm/xfrm_policy.c | 2 +-
6 files changed, 48 insertions(+), 65 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 2a46cba..d9b4e78 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -352,7 +352,8 @@ static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
}
extern int dst_discard(struct sk_buff *skb);
-extern void *dst_alloc(struct dst_ops * ops, int initial_ref);
+extern void *dst_alloc(struct dst_ops * ops, struct net_device *dev,
+ int initial_ref, int initial_obsolete, int flags);
extern void __dst_free(struct dst_entry * dst);
extern struct dst_entry *dst_destroy(struct dst_entry * dst);
diff --git a/net/core/dst.c b/net/core/dst.c
index 91104d3..9505778 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -166,7 +166,8 @@ EXPORT_SYMBOL(dst_discard);
const u32 dst_default_metrics[RTAX_MAX];
-void *dst_alloc(struct dst_ops *ops, int initial_ref)
+void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
+ int initial_ref, int initial_obsolete, int flags)
{
struct dst_entry *dst;
@@ -177,12 +178,19 @@ void *dst_alloc(struct dst_ops *ops, int initial_ref)
dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC);
if (!dst)
return NULL;
- atomic_set(&dst->__refcnt, initial_ref);
dst->ops = ops;
- dst->lastuse = jiffies;
- dst->path = dst;
- dst->input = dst->output = dst_discard;
+ dst->dev = dev;
+ if (dev)
+ dev_hold(dev);
dst_init_metrics(dst, dst_default_metrics, true);
+ dst->path = dst;
+ dst->input = dst_discard;
+ dst->output = dst_discard;
+
+ dst->obsolete = initial_obsolete;
+ atomic_set(&dst->__refcnt, initial_ref);
+ dst->lastuse = jiffies;
+ dst->flags = flags;
#if RT_CACHE_DEBUG >= 2
atomic_inc(&dst_total);
#endif
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 9f09d4f..f489b08 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1125,13 +1125,10 @@ make_route:
if (dev_out->flags & IFF_LOOPBACK)
flags |= RTCF_LOCAL;
- rt = dst_alloc(&dn_dst_ops, 0);
+ rt = dst_alloc(&dn_dst_ops, dev_out, 1, 0, DST_HOST);
if (rt == NULL)
goto e_nobufs;
- atomic_set(&rt->dst.__refcnt, 1);
- rt->dst.flags = DST_HOST;
-
rt->fld.saddr = oldflp->saddr;
rt->fld.daddr = oldflp->daddr;
rt->fld.flowidn_oif = oldflp->flowidn_oif;
@@ -1146,8 +1143,6 @@ make_route:
rt->rt_dst_map = fld.daddr;
rt->rt_src_map = fld.saddr;
- rt->dst.dev = dev_out;
- dev_hold(dev_out);
rt->dst.neighbour = neigh;
neigh = NULL;
@@ -1399,7 +1394,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
}
make_route:
- rt = dst_alloc(&dn_dst_ops, 0);
+ rt = dst_alloc(&dn_dst_ops, out_dev, 0, 0, DST_HOST);
if (rt == NULL)
goto e_nobufs;
@@ -1419,9 +1414,7 @@ make_route:
rt->fld.flowidn_iif = in_dev->ifindex;
rt->fld.flowidn_mark = fld.flowidn_mark;
- rt->dst.flags = DST_HOST;
rt->dst.neighbour = neigh;
- rt->dst.dev = out_dev;
rt->dst.lastuse = jiffies;
rt->dst.output = dn_rt_bug;
switch(res.type) {
@@ -1440,8 +1433,6 @@ make_route:
rt->dst.input = dst_discard;
}
rt->rt_flags = flags;
- if (rt->dst.dev)
- dev_hold(rt->dst.dev);
err = dn_rt_set_next_hop(rt, &res);
if (err)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 96dd498..d0c78ec 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1103,21 +1103,17 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
rt->rt_type = type;
}
-static struct rtable *rt_dst_alloc(bool nopolicy, bool noxfrm)
+static struct rtable *rt_dst_alloc(struct net_device *dev,
+ bool nopolicy, bool noxfrm)
{
- struct rtable *rt = dst_alloc(&ipv4_dst_ops, 1);
- if (rt) {
- rt->dst.obsolete = -1;
-
- /* To avoid expensive rcu stuff for this uncached dst, we set
- * DST_NOCACHE so that dst_release() can free dst without
- * waiting a grace period.
- */
- rt->dst.flags = DST_NOCACHE | DST_HOST |
- (nopolicy ? DST_NOPOLICY : 0) |
- (noxfrm ? DST_NOXFRM : 0);
- }
- return rt;
+ /* To avoid expensive rcu stuff for this uncached dst, we set
+ * DST_NOCACHE so that dst_release() can free dst without
+ * waiting a grace period.
+ */
+ return dst_alloc(&ipv4_dst_ops, dev, 1, -1,
+ DST_NOCACHE | DST_HOST |
+ (nopolicy ? DST_NOPOLICY : 0) |
+ (noxfrm ? DST_NOXFRM : 0));
}
/* called in rcu_read_lock() section */
@@ -1149,7 +1145,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
if (err < 0)
goto e_err;
}
- rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
+ rth = rt_dst_alloc(init_net.loopback_dev,
+ IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
if (!rth)
goto e_nobufs;
@@ -1165,8 +1162,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rth->dst.tclassid = itag;
#endif
rth->rt_iif = dev->ifindex;
- rth->dst.dev = init_net.loopback_dev;
- dev_hold(rth->dst.dev);
rth->rt_oif = 0;
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
@@ -1284,7 +1279,8 @@ static int __mkroute_input(struct sk_buff *skb,
}
}
- rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY),
+ rth = rt_dst_alloc(out_dev->dev,
+ IN_DEV_CONF_GET(in_dev, NOPOLICY),
IN_DEV_CONF_GET(out_dev, NOXFRM));
if (!rth) {
err = -ENOBUFS;
@@ -1299,8 +1295,6 @@ static int __mkroute_input(struct sk_buff *skb,
rth->rt_src = saddr;
rth->rt_gateway = daddr;
rth->rt_iif = in_dev->dev->ifindex;
- rth->dst.dev = (out_dev)->dev;
- dev_hold(rth->dst.dev);
rth->rt_oif = 0;
rth->rt_spec_dst= spec_dst;
@@ -1453,7 +1447,8 @@ brd_input:
RT_CACHE_STAT_INC(in_brd);
local_input:
- rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
+ rth = rt_dst_alloc(net->loopback_dev,
+ IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
if (!rth)
goto e_nobufs;
@@ -1470,8 +1465,6 @@ local_input:
rth->dst.tclassid = itag;
#endif
rth->rt_iif = dev->ifindex;
- rth->dst.dev = net->loopback_dev;
- dev_hold(rth->dst.dev);
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
rth->dst.input= ip_local_deliver;
@@ -1618,7 +1611,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
fi = NULL;
}
- rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY),
+ rth = rt_dst_alloc(dev_out,
+ IN_DEV_CONF_GET(in_dev, NOPOLICY),
IN_DEV_CONF_GET(in_dev, NOXFRM));
if (!rth)
return ERR_PTR(-ENOBUFS);
@@ -1631,10 +1625,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
rth->rt_dst = fl4->daddr;
rth->rt_src = fl4->saddr;
rth->rt_iif = 0;
- /* get references to the devices that are to be hold by the routing
- cache entry */
- rth->dst.dev = dev_out;
- dev_hold(dev_out);
rth->rt_gateway = fl4->daddr;
rth->rt_spec_dst= fl4->saddr;
@@ -1885,7 +1875,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
{
- struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, 1);
+ struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, 0, 0);
struct rtable *ort = (struct rtable *) dst_orig;
if (rt) {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 6814c87..018db5d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -220,9 +220,10 @@ static struct rt6_info ip6_blk_hole_entry_template = {
#endif
/* allocate dst with ip6_dst_ops */
-static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops)
+static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops,
+ struct net_device *dev)
{
- return (struct rt6_info *)dst_alloc(ops, 0);
+ return (struct rt6_info *)dst_alloc(ops, dev, 0, 0, 0);
}
static void ip6_dst_destroy(struct dst_entry *dst)
@@ -874,10 +875,10 @@ EXPORT_SYMBOL(ip6_route_output);
struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
{
- struct rt6_info *rt = dst_alloc(&ip6_dst_blackhole_ops, 1);
- struct rt6_info *ort = (struct rt6_info *) dst_orig;
+ struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig;
struct dst_entry *new = NULL;
+ rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0);
if (rt) {
new = &rt->dst;
@@ -886,9 +887,6 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
new->output = dst_discard;
dst_copy_metrics(new, &ort->dst);
- new->dev = ort->dst.dev;
- if (new->dev)
- dev_hold(new->dev);
rt->rt6i_idev = ort->rt6i_idev;
if (rt->rt6i_idev)
in6_dev_hold(rt->rt6i_idev);
@@ -1031,13 +1029,12 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
if (unlikely(idev == NULL))
return NULL;
- rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+ rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev);
if (unlikely(rt == NULL)) {
in6_dev_put(idev);
goto out;
}
- dev_hold(dev);
if (neigh)
neigh_hold(neigh);
else {
@@ -1046,7 +1043,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
neigh = NULL;
}
- rt->rt6i_dev = dev;
rt->rt6i_idev = idev;
rt->rt6i_nexthop = neigh;
atomic_set(&rt->dst.__refcnt, 1);
@@ -1205,7 +1201,7 @@ int ip6_route_add(struct fib6_config *cfg)
goto out;
}
- rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+ rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL);
if (rt == NULL) {
err = -ENOMEM;
@@ -1714,7 +1710,8 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
{
struct net *net = dev_net(ort->rt6i_dev);
- struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+ struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
+ ort->dst.dev);
if (rt) {
rt->dst.input = ort->dst.input;
@@ -1722,9 +1719,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
dst_copy_metrics(&rt->dst, &ort->dst);
rt->dst.error = ort->dst.error;
- rt->dst.dev = ort->dst.dev;
- if (rt->dst.dev)
- dev_hold(rt->dst.dev);
rt->rt6i_idev = ort->rt6i_idev;
if (rt->rt6i_idev)
in6_dev_hold(rt->rt6i_idev);
@@ -1994,7 +1988,8 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
int anycast)
{
struct net *net = dev_net(idev->dev);
- struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
+ struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
+ net->loopback_dev);
struct neighbour *neigh;
if (rt == NULL) {
@@ -2004,13 +1999,11 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
return ERR_PTR(-ENOMEM);
}
- dev_hold(net->loopback_dev);
in6_dev_hold(idev);
rt->dst.flags = DST_HOST;
rt->dst.input = ip6_input;
rt->dst.output = ip6_output;
- rt->rt6i_dev = net->loopback_dev;
rt->rt6i_idev = idev;
dst_metric_set(&rt->dst, RTAX_HOPLIMIT, -1);
rt->dst.obsolete = -1;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 1ba0258..2404b53 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1348,7 +1348,7 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
default:
BUG();
}
- xdst = dst_alloc(dst_ops, 0);
+ xdst = dst_alloc(dst_ops, NULL, 0, 0, 0);
xfrm_policy_put_afinfo(afinfo);
if (likely(xdst))
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 RFC 6/8] net: Use non-zero allocations in dst_alloc().
From: David Miller @ 2011-03-13 0:37 UTC (permalink / raw)
To: netdev
Make dst_alloc() and it's users explicitly initialize the entire
entry.
The zero'ing done by kmem_cache_zalloc() was almost entirely
redundant.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/core/dst.c | 20 ++++++++++--
net/decnet/dn_route.c | 2 +
net/ipv4/route.c | 81 ++++++++++++++++++++++++++++--------------------
net/ipv6/route.c | 8 ++++-
net/xfrm/xfrm_policy.c | 1 +
5 files changed, 74 insertions(+), 38 deletions(-)
diff --git a/net/core/dst.c b/net/core/dst.c
index 9505778..30f0093 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -175,22 +175,36 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
if (ops->gc(ops))
return NULL;
}
- dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC);
+ dst = kmem_cache_alloc(ops->kmem_cachep, GFP_ATOMIC);
if (!dst)
return NULL;
- dst->ops = ops;
+ dst->child = NULL;
dst->dev = dev;
if (dev)
dev_hold(dev);
+ dst->ops = ops;
dst_init_metrics(dst, dst_default_metrics, true);
+ dst->expires = 0UL;
dst->path = dst;
+ dst->neighbour = NULL;
+ dst->hh = NULL;
+#ifdef CONFIG_XFRM
+ dst->xfrm = NULL;
+#endif
dst->input = dst_discard;
dst->output = dst_discard;
-
+ dst->error = 0;
dst->obsolete = initial_obsolete;
+ dst->header_len = 0;
+ dst->trailer_len = 0;
+#ifdef CONFIG_IP_ROUTE_CLASSID
+ dst->tclassid = 0;
+#endif
atomic_set(&dst->__refcnt, initial_ref);
+ dst->__use = 0;
dst->lastuse = jiffies;
dst->flags = flags;
+ dst->next = NULL;
#if RT_CACHE_DEBUG >= 2
atomic_inc(&dst_total);
#endif
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index f489b08..74544bc 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1129,6 +1129,7 @@ make_route:
if (rt == NULL)
goto e_nobufs;
+ memset(&rt->fld, 0, sizeof(rt->fld));
rt->fld.saddr = oldflp->saddr;
rt->fld.daddr = oldflp->daddr;
rt->fld.flowidn_oif = oldflp->flowidn_oif;
@@ -1398,6 +1399,7 @@ make_route:
if (rt == NULL)
goto e_nobufs;
+ memset(&rt->fld, 0, sizeof(rt->fld));
rt->rt_saddr = fld.saddr;
rt->rt_daddr = fld.daddr;
rt->rt_gateway = fld.daddr;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d0c78ec..0b02eb3 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1100,7 +1100,6 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
#endif
set_class_tag(rt, itag);
#endif
- rt->rt_type = type;
}
static struct rtable *rt_dst_alloc(struct net_device *dev,
@@ -1150,24 +1149,27 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
if (!rth)
goto e_nobufs;
+#ifdef CONFIG_IP_ROUTE_CLASSID
+ rth->dst.tclassid = itag;
+#endif
rth->dst.output = ip_rt_bug;
rth->rt_key_dst = daddr;
- rth->rt_dst = daddr;
- rth->rt_tos = tos;
- rth->rt_mark = skb->mark;
rth->rt_key_src = saddr;
+ rth->rt_genid = rt_genid(dev_net(dev));
+ rth->rt_flags = RTCF_MULTICAST;
+ rth->rt_type = RTN_MULTICAST;
+ rth->rt_tos = tos;
+ rth->rt_dst = daddr;
rth->rt_src = saddr;
-#ifdef CONFIG_IP_ROUTE_CLASSID
- rth->dst.tclassid = itag;
-#endif
rth->rt_iif = dev->ifindex;
rth->rt_oif = 0;
+ rth->rt_mark = skb->mark;
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
- rth->rt_genid = rt_genid(dev_net(dev));
- rth->rt_flags = RTCF_MULTICAST;
- rth->rt_type = RTN_MULTICAST;
+ rth->rt_peer_genid = 0;
+ rth->peer = NULL;
+ rth->fi = NULL;
if (our) {
rth->dst.input= ip_local_deliver;
rth->rt_flags |= RTCF_LOCAL;
@@ -1288,24 +1290,27 @@ static int __mkroute_input(struct sk_buff *skb,
}
rth->rt_key_dst = daddr;
- rth->rt_dst = daddr;
- rth->rt_tos = tos;
- rth->rt_mark = skb->mark;
rth->rt_key_src = saddr;
+ rth->rt_genid = rt_genid(dev_net(rth->dst.dev));
+ rth->rt_flags = flags;
+ rth->rt_type = res->type;
+ rth->rt_tos = tos;
+ rth->rt_dst = daddr;
rth->rt_src = saddr;
- rth->rt_gateway = daddr;
rth->rt_iif = in_dev->dev->ifindex;
rth->rt_oif = 0;
+ rth->rt_mark = skb->mark;
+ rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
+ rth->rt_peer_genid = 0;
+ rth->peer = NULL;
+ rth->fi = NULL;
rth->dst.input = ip_forward;
rth->dst.output = ip_output;
- rth->rt_genid = rt_genid(dev_net(rth->dst.dev));
rt_set_nexthop(rth, NULL, res, res->fi, res->type, itag);
- rth->rt_flags = flags;
-
*result = rth;
err = 0;
cleanup:
@@ -1452,29 +1457,33 @@ local_input:
if (!rth)
goto e_nobufs;
+ rth->dst.input= ip_local_deliver;
rth->dst.output= ip_rt_bug;
- rth->rt_genid = rt_genid(net);
+#ifdef CONFIG_IP_ROUTE_CLASSID
+ rth->dst.tclassid = itag;
+#endif
rth->rt_key_dst = daddr;
- rth->rt_dst = daddr;
- rth->rt_tos = tos;
- rth->rt_mark = skb->mark;
rth->rt_key_src = saddr;
+ rth->rt_genid = rt_genid(net);
+ rth->rt_flags = flags|RTCF_LOCAL;
+ rth->rt_type = res.type;
+ rth->rt_tos = tos;
+ rth->rt_dst = daddr;
rth->rt_src = saddr;
-#ifdef CONFIG_IP_ROUTE_CLASSID
- rth->dst.tclassid = itag;
-#endif
rth->rt_iif = dev->ifindex;
+ rth->rt_oif = 0;
+ rth->rt_mark = skb->mark;
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
- rth->dst.input= ip_local_deliver;
- rth->rt_flags = flags|RTCF_LOCAL;
+ rth->rt_peer_genid = 0;
+ rth->peer = NULL;
+ rth->fi = NULL;
if (res.type == RTN_UNREACHABLE) {
rth->dst.input= ip_error;
rth->dst.error= -err;
rth->rt_flags &= ~RTCF_LOCAL;
}
- rth->rt_type = res.type;
rth = rt_finalize(rth, skb);
err = 0;
if (IS_ERR(rth))
@@ -1617,19 +1626,24 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
if (!rth)
return ERR_PTR(-ENOBUFS);
+ rth->dst.output = ip_output;
+
rth->rt_key_dst = oldflp4->daddr;
- rth->rt_tos = tos;
rth->rt_key_src = oldflp4->saddr;
- rth->rt_oif = oldflp4->flowi4_oif;
- rth->rt_mark = oldflp4->flowi4_mark;
+ rth->rt_genid = rt_genid(dev_net(dev_out));
+ rth->rt_flags = flags;
+ rth->rt_type = type;
+ rth->rt_tos = tos;
rth->rt_dst = fl4->daddr;
rth->rt_src = fl4->saddr;
rth->rt_iif = 0;
+ rth->rt_oif = oldflp4->flowi4_oif;
+ rth->rt_mark = oldflp4->flowi4_mark;
rth->rt_gateway = fl4->daddr;
rth->rt_spec_dst= fl4->saddr;
-
- rth->dst.output=ip_output;
- rth->rt_genid = rt_genid(dev_net(dev_out));
+ rth->rt_peer_genid = 0;
+ rth->peer = NULL;
+ rth->fi = NULL;
RT_CACHE_STAT_INC(out_slow_tot);
@@ -1657,7 +1671,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
rt_set_nexthop(rth, oldflp4, res, fi, type, 0);
- rth->rt_flags = flags;
return rth;
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 018db5d..d434cd5 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -223,7 +223,11 @@ static struct rt6_info ip6_blk_hole_entry_template = {
static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops,
struct net_device *dev)
{
- return (struct rt6_info *)dst_alloc(ops, dev, 0, 0, 0);
+ struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, 0);
+
+ memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry));
+
+ return rt;
}
static void ip6_dst_destroy(struct dst_entry *dst)
@@ -880,6 +884,8 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0);
if (rt) {
+ memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry));
+
new = &rt->dst;
new->__use = 1;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 2404b53..7a028ad 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1349,6 +1349,7 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
BUG();
}
xdst = dst_alloc(dst_ops, NULL, 0, 0, 0);
+ memset(&xdst->u.rt6.rt6i_table, 0, sizeof(*xdst) - sizeof(struct dst_entry));
xfrm_policy_put_afinfo(afinfo);
if (likely(xdst))
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 RFC 7/8] ipv4: Kill rt_key_{src,dst} from struct rtable.
From: David Miller @ 2011-03-13 0:37 UTC (permalink / raw)
To: netdev
They are always used in contexts where they can be reconstituted,
or where the finally resolved rt->rt_{src,dst} is semantically
equivalent.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/route.h | 8 ++------
net/ipv4/ipmr.c | 4 ++--
net/ipv4/route.c | 24 +++++++-----------------
net/ipv4/xfrm4_policy.c | 2 --
4 files changed, 11 insertions(+), 27 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index 78e8ce1..154e589 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -53,10 +53,6 @@ struct fib_info;
struct rtable {
struct dst_entry dst;
- /* Lookup key. */
- __be32 rt_key_dst;
- __be32 rt_key_src;
-
int rt_genid;
unsigned rt_flags;
__u16 rt_type;
@@ -256,8 +252,8 @@ static inline struct rtable *ip_route_newports(struct rtable *rt,
struct flowi4 fl4 = {
.flowi4_oif = rt->rt_oif,
.flowi4_mark = rt->rt_mark,
- .daddr = rt->rt_key_dst,
- .saddr = rt->rt_key_src,
+ .daddr = rt->rt_dst,
+ .saddr = rt->rt_src,
.flowi4_tos = rt->rt_tos,
.flowi4_proto = protocol,
.fl4_sport = sport,
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 1f62eae..0441b26 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1791,8 +1791,8 @@ dont_forward:
static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct rtable *rt)
{
struct flowi4 fl4 = {
- .daddr = rt->rt_key_dst,
- .saddr = rt->rt_key_src,
+ .daddr = rt->rt_dst,
+ .saddr = rt->rt_src,
.flowi4_tos = rt->rt_tos,
.flowi4_oif = rt->rt_oif,
.flowi4_iif = rt->rt_iif,
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 0b02eb3..21fb343 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -978,8 +978,8 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt)
src = rt->rt_src;
else {
struct flowi4 fl4 = {
- .daddr = rt->rt_key_dst,
- .saddr = rt->rt_key_src,
+ .daddr = rt->rt_dst,
+ .saddr = rt->rt_src,
.flowi4_tos = rt->rt_tos,
.flowi4_oif = rt->rt_oif,
.flowi4_iif = rt->rt_iif,
@@ -1154,8 +1154,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
#endif
rth->dst.output = ip_rt_bug;
- rth->rt_key_dst = daddr;
- rth->rt_key_src = saddr;
rth->rt_genid = rt_genid(dev_net(dev));
rth->rt_flags = RTCF_MULTICAST;
rth->rt_type = RTN_MULTICAST;
@@ -1289,8 +1287,6 @@ static int __mkroute_input(struct sk_buff *skb,
goto cleanup;
}
- rth->rt_key_dst = daddr;
- rth->rt_key_src = saddr;
rth->rt_genid = rt_genid(dev_net(rth->dst.dev));
rth->rt_flags = flags;
rth->rt_type = res->type;
@@ -1463,8 +1459,6 @@ local_input:
rth->dst.tclassid = itag;
#endif
- rth->rt_key_dst = daddr;
- rth->rt_key_src = saddr;
rth->rt_genid = rt_genid(net);
rth->rt_flags = flags|RTCF_LOCAL;
rth->rt_type = res.type;
@@ -1628,8 +1622,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
rth->dst.output = ip_output;
- rth->rt_key_dst = oldflp4->daddr;
- rth->rt_key_src = oldflp4->saddr;
rth->rt_genid = rt_genid(dev_net(dev_out));
rth->rt_flags = flags;
rth->rt_type = type;
@@ -1903,8 +1895,6 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
if (new->dev)
dev_hold(new->dev);
- rt->rt_key_dst = ort->rt_key_dst;
- rt->rt_key_src = ort->rt_key_src;
rt->rt_tos = ort->rt_tos;
rt->rt_iif = ort->rt_iif;
rt->rt_oif = ort->rt_oif;
@@ -1955,7 +1945,7 @@ struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4,
}
EXPORT_SYMBOL_GPL(ip_route_output_flow);
-static int rt_fill_info(struct net *net,
+static int rt_fill_info(struct net *net, __be32 src,
struct sk_buff *skb, u32 pid, u32 seq, int event,
int nowait, unsigned int flags)
{
@@ -1985,9 +1975,9 @@ static int rt_fill_info(struct net *net,
NLA_PUT_BE32(skb, RTA_DST, rt->rt_dst);
- if (rt->rt_key_src) {
+ if (src) {
r->rtm_src_len = 32;
- NLA_PUT_BE32(skb, RTA_SRC, rt->rt_key_src);
+ NLA_PUT_BE32(skb, RTA_SRC, src);
}
if (rt->dst.dev)
NLA_PUT_U32(skb, RTA_OIF, rt->dst.dev->ifindex);
@@ -1997,7 +1987,7 @@ static int rt_fill_info(struct net *net,
#endif
if (rt_is_input_route(rt))
NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
- else if (rt->rt_src != rt->rt_key_src)
+ else if (rt->rt_src != src)
NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src);
if (rt->rt_dst != rt->rt_gateway)
@@ -2139,7 +2129,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
if (rtm->rtm_flags & RTM_F_NOTIFY)
rt->rt_flags |= RTCF_NOTIFY;
- err = rt_fill_info(net, skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
+ err = rt_fill_info(net, src, skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
RTM_NEWROUTE, 0, 0);
if (err <= 0)
goto errout_free;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 13e0e7f..813fb34 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -71,8 +71,6 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
struct rtable *rt = (struct rtable *)xdst->route;
const struct flowi4 *fl4 = &fl->u.ip4;
- rt->rt_key_dst = fl4->daddr;
- rt->rt_key_src = fl4->saddr;
rt->rt_tos = fl4->flowi4_tos;
rt->rt_iif = fl4->flowi4_iif;
rt->rt_oif = fl4->flowi4_oif;
--
1.7.4.1
^ permalink raw reply related
* [PATCH v4 RFC 8/8] ipv4: Use caller's on-stack flowi as-is in output route lookups.
From: David Miller @ 2011-03-13 0:38 UTC (permalink / raw)
To: netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/route.h | 2 +-
net/ipv4/route.c | 134 ++++++++++++++++++++++++--------------------------
2 files changed, 65 insertions(+), 71 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index 154e589..304cd6c 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -117,7 +117,7 @@ extern int ip_rt_init(void);
extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32 src, struct net_device *dev);
extern void rt_cache_flush(struct net *net, int how);
-extern struct rtable *__ip_route_output_key(struct net *, const struct flowi4 *flp);
+extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
struct sock *sk);
extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 21fb343..ab0053b 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1037,7 +1037,7 @@ static unsigned int ipv4_default_mtu(const struct dst_entry *dst)
return mtu;
}
-static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4,
+static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,
struct fib_info *fi)
{
struct inet_peer *peer;
@@ -1046,7 +1046,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4,
/* If a peer entry exists for this destination, we must hook
* it up in order to get at cached metrics.
*/
- if (oldflp4 && (oldflp4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS))
+ if (fl4 && (fl4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS))
create = 1;
rt->peer = peer = inet_getpeer_v4(rt->rt_dst, create);
@@ -1073,7 +1073,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *oldflp4,
}
}
-static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
+static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *fl4,
const struct fib_result *res,
struct fib_info *fi, u16 type, u32 itag)
{
@@ -1083,7 +1083,7 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
if (FIB_RES_GW(*res) &&
FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
rt->rt_gateway = FIB_RES_GW(*res);
- rt_init_metrics(rt, oldflp4, fi);
+ rt_init_metrics(rt, fl4, fi);
#ifdef CONFIG_IP_ROUTE_CLASSID
dst->tclassid = FIB_RES_NH(*res).nh_tclassid;
#endif
@@ -1571,12 +1571,11 @@ EXPORT_SYMBOL(ip_route_input);
/* called with rcu_read_lock() */
static struct rtable *__mkroute_output(const struct fib_result *res,
const struct flowi4 *fl4,
- const struct flowi4 *oldflp4,
struct net_device *dev_out,
unsigned int flags)
{
struct fib_info *fi = res->fi;
- u32 tos = RT_FL_TOS(oldflp4);
+ u32 tos = RT_FL_TOS(fl4);
struct in_device *in_dev;
u16 type = res->type;
struct rtable *rth;
@@ -1603,8 +1602,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
fi = NULL;
} else if (type == RTN_MULTICAST) {
flags |= RTCF_MULTICAST | RTCF_LOCAL;
- if (!ip_check_mc_rcu(in_dev, oldflp4->daddr, oldflp4->saddr,
- oldflp4->flowi4_proto))
+ if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr,
+ fl4->flowi4_proto))
flags &= ~RTCF_LOCAL;
/* If multicast route do not exist use
* default one, but do not gateway in this case.
@@ -1629,8 +1628,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
rth->rt_dst = fl4->daddr;
rth->rt_src = fl4->saddr;
rth->rt_iif = 0;
- rth->rt_oif = oldflp4->flowi4_oif;
- rth->rt_mark = oldflp4->flowi4_mark;
+ rth->rt_oif = fl4->flowi4_oif;
+ rth->rt_mark = fl4->flowi4_mark;
rth->rt_gateway = fl4->daddr;
rth->rt_spec_dst= fl4->saddr;
rth->rt_peer_genid = 0;
@@ -1653,7 +1652,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
#ifdef CONFIG_IP_MROUTE
if (type == RTN_MULTICAST) {
if (IN_DEV_MFORWARD(in_dev) &&
- !ipv4_is_local_multicast(oldflp4->daddr)) {
+ !ipv4_is_local_multicast(fl4->daddr)) {
rth->dst.input = ip_mr_input;
rth->dst.output = ip_mc_output;
}
@@ -1661,7 +1660,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
#endif
}
- rt_set_nexthop(rth, oldflp4, res, fi, type, 0);
+ rt_set_nexthop(rth, fl4, res, fi, type, 0);
return rth;
}
@@ -1670,13 +1669,12 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
* Major route resolver routine.
*/
-struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldflp4)
+struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
{
- u32 tos = RT_FL_TOS(oldflp4);
- struct flowi4 fl4;
- struct fib_result res;
- unsigned int flags = 0;
struct net_device *dev_out = NULL;
+ u32 tos = RT_FL_TOS(fl4);
+ unsigned int flags = 0;
+ struct fib_result res;
struct rtable *rth;
res.fi = NULL;
@@ -1684,21 +1682,17 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
res.r = NULL;
#endif
- fl4.flowi4_oif = oldflp4->flowi4_oif;
- fl4.flowi4_iif = net->loopback_dev->ifindex;
- fl4.flowi4_mark = oldflp4->flowi4_mark;
- fl4.daddr = oldflp4->daddr;
- fl4.saddr = oldflp4->saddr;
- fl4.flowi4_tos = tos & IPTOS_RT_MASK;
- fl4.flowi4_scope = ((tos & RTO_ONLINK) ?
- RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
+ fl4->flowi4_iif = net->loopback_dev->ifindex;
+ fl4->flowi4_tos = tos & IPTOS_RT_MASK;
+ fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
+ RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
rcu_read_lock();
- if (oldflp4->saddr) {
+ if (fl4->saddr) {
rth = ERR_PTR(-EINVAL);
- if (ipv4_is_multicast(oldflp4->saddr) ||
- ipv4_is_lbcast(oldflp4->saddr) ||
- ipv4_is_zeronet(oldflp4->saddr))
+ if (ipv4_is_multicast(fl4->saddr) ||
+ ipv4_is_lbcast(fl4->saddr) ||
+ ipv4_is_zeronet(fl4->saddr))
goto out;
/* I removed check for oif == dev_out->oif here.
@@ -1709,11 +1703,11 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
of another iface. --ANK
*/
- if (oldflp4->flowi4_oif == 0 &&
- (ipv4_is_multicast(oldflp4->daddr) ||
- ipv4_is_lbcast(oldflp4->daddr))) {
+ if (fl4->flowi4_oif == 0 &&
+ (ipv4_is_multicast(fl4->daddr) ||
+ ipv4_is_lbcast(fl4->daddr))) {
/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
- dev_out = __ip_dev_find(net, oldflp4->saddr, false);
+ dev_out = __ip_dev_find(net, fl4->saddr, false);
if (dev_out == NULL)
goto out;
@@ -1732,20 +1726,20 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
Luckily, this hack is good workaround.
*/
- fl4.flowi4_oif = dev_out->ifindex;
+ fl4->flowi4_oif = dev_out->ifindex;
goto make_route;
}
- if (!(oldflp4->flowi4_flags & FLOWI_FLAG_ANYSRC)) {
+ if (!(fl4->flowi4_flags & FLOWI_FLAG_ANYSRC)) {
/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
- if (!__ip_dev_find(net, oldflp4->saddr, false))
+ if (!__ip_dev_find(net, fl4->saddr, false))
goto out;
}
}
- if (oldflp4->flowi4_oif) {
- dev_out = dev_get_by_index_rcu(net, oldflp4->flowi4_oif);
+ if (fl4->flowi4_oif) {
+ dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif);
rth = ERR_PTR(-ENODEV);
if (dev_out == NULL)
goto out;
@@ -1755,37 +1749,37 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
rth = ERR_PTR(-ENETUNREACH);
goto out;
}
- if (ipv4_is_local_multicast(oldflp4->daddr) ||
- ipv4_is_lbcast(oldflp4->daddr)) {
- if (!fl4.saddr)
- fl4.saddr = inet_select_addr(dev_out, 0,
- RT_SCOPE_LINK);
+ if (ipv4_is_local_multicast(fl4->daddr) ||
+ ipv4_is_lbcast(fl4->daddr)) {
+ if (!fl4->saddr)
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ RT_SCOPE_LINK);
goto make_route;
}
- if (!fl4.saddr) {
- if (ipv4_is_multicast(oldflp4->daddr))
- fl4.saddr = inet_select_addr(dev_out, 0,
- fl4.flowi4_scope);
- else if (!oldflp4->daddr)
- fl4.saddr = inet_select_addr(dev_out, 0,
- RT_SCOPE_HOST);
+ if (fl4->saddr) {
+ if (ipv4_is_multicast(fl4->daddr))
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ fl4->flowi4_scope);
+ else if (!fl4->daddr)
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ RT_SCOPE_HOST);
}
}
- if (!fl4.daddr) {
- fl4.daddr = fl4.saddr;
- if (!fl4.daddr)
- fl4.daddr = fl4.saddr = htonl(INADDR_LOOPBACK);
+ if (!fl4->daddr) {
+ fl4->daddr = fl4->saddr;
+ if (!fl4->daddr)
+ fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK);
dev_out = net->loopback_dev;
- fl4.flowi4_oif = net->loopback_dev->ifindex;
+ fl4->flowi4_oif = net->loopback_dev->ifindex;
res.type = RTN_LOCAL;
flags |= RTCF_LOCAL;
goto make_route;
}
- if (fib_lookup(net, &fl4, &res)) {
+ if (fib_lookup(net, fl4, &res)) {
res.fi = NULL;
- if (oldflp4->flowi4_oif) {
+ if (fl4->flowi4_oif) {
/* Apparently, routing tables are wrong. Assume,
that the destination is on link.
@@ -1804,9 +1798,9 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
likely IPv6, but we do not.
*/
- if (fl4.saddr == 0)
- fl4.saddr = inet_select_addr(dev_out, 0,
- RT_SCOPE_LINK);
+ if (fl4->saddr == 0)
+ fl4->saddr = inet_select_addr(dev_out, 0,
+ RT_SCOPE_LINK);
res.type = RTN_UNICAST;
goto make_route;
}
@@ -1815,36 +1809,36 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *oldfl
}
if (res.type == RTN_LOCAL) {
- if (!fl4.saddr) {
+ if (!fl4->saddr) {
if (res.fi->fib_prefsrc)
- fl4.saddr = res.fi->fib_prefsrc;
+ fl4->saddr = res.fi->fib_prefsrc;
else
- fl4.saddr = fl4.daddr;
+ fl4->saddr = fl4->daddr;
}
dev_out = net->loopback_dev;
- fl4.flowi4_oif = dev_out->ifindex;
+ fl4->flowi4_oif = dev_out->ifindex;
res.fi = NULL;
flags |= RTCF_LOCAL;
goto make_route;
}
#ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (res.fi->fib_nhs > 1 && fl4.flowi4_oif == 0)
+ if (res.fi->fib_nhs > 1 && fl4->flowi4_oif == 0)
fib_select_multipath(&res);
else
#endif
- if (!res.prefixlen && res.type == RTN_UNICAST && !fl4.flowi4_oif)
+ if (!res.prefixlen && res.type == RTN_UNICAST && !fl4->flowi4_oif)
fib_select_default(&res);
- if (!fl4.saddr)
- fl4.saddr = FIB_RES_PREFSRC(res);
+ if (!fl4->saddr)
+ fl4->saddr = FIB_RES_PREFSRC(res);
dev_out = FIB_RES_DEV(res);
- fl4.flowi4_oif = dev_out->ifindex;
+ fl4->flowi4_oif = dev_out->ifindex;
make_route:
- rth = __mkroute_output(&res, &fl4, oldflp4, dev_out, flags);
+ rth = __mkroute_output(&res, fl4, dev_out, flags);
if (!IS_ERR(rth))
rth = rt_finalize(rth, NULL);
--
1.7.4.1
^ permalink raw reply related
* Re: [RFC v2 PATCH 1/9] crypto: authencesn - Add algorithm to handle IPsec extended sequence numbers
From: Herbert Xu @ 2011-03-13 6:30 UTC (permalink / raw)
To: Steffen Klassert
Cc: David Miller, Alex Badea, Andreas Gruenbacher, netdev,
linux-crypto
In-Reply-To: <20110308100458.GC31402@secunet.com>
On Tue, Mar 08, 2011 at 11:04:58AM +0100, Steffen Klassert wrote:
>
> + return crypto_authenc_esn_genicv(req, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
BTW, we should get rid of these MAY_SLEEP flags. Originally I
included them for the IPsec encryption path because that happens
to be sleepable. We should instead be getting it from the request
itself.
Also, as soon as we enter the async path it becomes unsleepable.
Of course this affects the existing authenc file as well.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [RFC v2 PATCH 2/9] xfrm: Add basic infrastructure to support IPsec extended sequence numbers
From: Herbert Xu @ 2011-03-13 6:44 UTC (permalink / raw)
To: Steffen Klassert
Cc: David Miller, Alex Badea, Andreas Gruenbacher, netdev,
linux-crypto
In-Reply-To: <20110308100543.GD31402@secunet.com>
On Tue, Mar 08, 2011 at 11:05:43AM +0100, Steffen Klassert wrote:
> This patch adds the struct xfrm_replay_state_esn which will be
> used to support IPsec extended sequence numbers and anti replay windows
> bigger than 32 packets. Also we add a function that returns the actual
> size of the xfrm_replay_state_esn, a xfrm netlink atribute and a xfrm state
> flag for the use of extended sequence numbers.
>
> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
All the remaining eight patches look good to me.
Dave, how would you like to handle this patch-set? As Steffen's
first crypto patch is completely self-contained, perhaps you could
just include it along with the rest of the series in your tree?
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [RFC v2 PATCH 2/9] xfrm: Add basic infrastructure to support IPsec extended sequence numbers
From: David Miller @ 2011-03-13 6:53 UTC (permalink / raw)
To: herbert; +Cc: steffen.klassert, abadea, agruen, netdev, linux-crypto
In-Reply-To: <20110313064457.GB10849@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Sun, 13 Mar 2011 14:44:57 +0800
> On Tue, Mar 08, 2011 at 11:05:43AM +0100, Steffen Klassert wrote:
>> This patch adds the struct xfrm_replay_state_esn which will be
>> used to support IPsec extended sequence numbers and anti replay windows
>> bigger than 32 packets. Also we add a function that returns the actual
>> size of the xfrm_replay_state_esn, a xfrm netlink atribute and a xfrm state
>> flag for the use of extended sequence numbers.
>>
>> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
>
> All the remaining eight patches look good to me.
>
> Dave, how would you like to handle this patch-set? As Steffen's
> first crypto patch is completely self-contained, perhaps you could
> just include it along with the rest of the series in your tree?
Sure, I can do that.
Can I add your ACK to all of the patches?
^ permalink raw reply
* Re: [RFC v2 PATCH 2/9] xfrm: Add basic infrastructure to support IPsec extended sequence numbers
From: Herbert Xu @ 2011-03-13 6:58 UTC (permalink / raw)
To: David Miller; +Cc: steffen.klassert, abadea, agruen, netdev, linux-crypto
In-Reply-To: <20110312.225333.193705435.davem@davemloft.net>
On Sat, Mar 12, 2011 at 10:53:33PM -0800, David Miller wrote:
>
> Sure, I can do that.
Thanks!
> Can I add your ACK to all of the patches?
Of course:
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* RE: how to utilize multi tx queue to sent packets
From: Jon Zhou @ 2011-03-13 9:06 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev@vger.kernel.org
In-Reply-To: <20110311090636.6e393f2b@nehalam>
> -----Original Message-----
> From: Stephen Hemminger [mailto:shemminger@vyatta.com]
> Sent: Saturday, March 12, 2011 1:07 AM
> To: Jon Zhou
> Cc: netdev@vger.kernel.org
> Subject: Re: how to utilize multi tx queue to sent packets
>
> On Thu, 10 Mar 2011 22:52:30 -0800
> Jon Zhou <Jon.Zhou@jdsu.com> wrote:
>
> > hi
> >
> > I am doing some test according to the
> > website:http://wiki.ipxwarzone.com/index.php5?title=Linux_packet_mmap
> >
> > use packet_mmap tx_ring to send packet.
> >
> > I modified the sample code "packetmmap.c" to make it send packets
> have different outer ip.
> > so that with the help of RSS, I can achieve higher throughput.
> >
> > but one thing I saw at the tx side, is that all the packets are sent
> via the same tx_queue,
> > which is conflict with what I saw at the rx side.
> > any idea to make it sent packets via different tx_queues? (spread
> across the tx_queues)
>
> You need to have multiple threads to get Tx scaling.
> In you case that also means multiple AF_PACKET sockets and separate
> rings.
>
> Or just run multiple copies of the same test each with a different IP
How does kernel know which tx_queue to use?
Will dev_queue_xmit determine tx_queue(sw queue) to send packets?
Or just let NIC select a tx_queue(hardware) ?
^ permalink raw reply
* Re: [PATCH] inetpeer: Don't disable BH for initial fast RCU lookup.
From: Eric Dumazet @ 2011-03-13 10:04 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20110308.145954.59682618.davem@davemloft.net>
Le mardi 08 mars 2011 à 14:59 -0800, David Miller a écrit :
> If modifications on other cpus are ok, then modifications to
> the tree during lookup done by the local cpu are ok too.
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> ---
> net/ipv4/inetpeer.c | 18 +++++++++---------
> 1 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
> index f604ffd..6442c35 100644
> --- a/net/ipv4/inetpeer.c
> +++ b/net/ipv4/inetpeer.c
> @@ -206,16 +206,16 @@ static int addr_compare(const struct inetpeer_addr *a,
> })
>
> /*
> - * Called with rcu_read_lock_bh()
> + * Called with rcu_read_lock()
> * Because we hold no lock against a writer, its quite possible we fall
> * in an endless loop.
> * But every pointer we follow is guaranteed to be valid thanks to RCU.
> * We exit from this function if number of links exceeds PEER_MAXDEPTH
> */
> -static struct inet_peer *lookup_rcu_bh(const struct inetpeer_addr *daddr,
> - struct inet_peer_base *base)
> +static struct inet_peer *lookup_rcu(const struct inetpeer_addr *daddr,
> + struct inet_peer_base *base)
> {
> - struct inet_peer *u = rcu_dereference_bh(base->root);
> + struct inet_peer *u = rcu_dereference(base->root);
> int count = 0;
>
> while (u != peer_avl_empty) {
> @@ -231,9 +231,9 @@ static struct inet_peer *lookup_rcu_bh(const struct inetpeer_addr *daddr,
> return u;
> }
> if (cmp == -1)
> - u = rcu_dereference_bh(u->avl_left);
> + u = rcu_dereference(u->avl_left);
> else
> - u = rcu_dereference_bh(u->avl_right);
> + u = rcu_dereference(u->avl_right);
> if (unlikely(++count == PEER_MAXDEPTH))
> break;
> }
> @@ -470,11 +470,11 @@ struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create)
> /* Look up for the address quickly, lockless.
> * Because of a concurrent writer, we might not find an existing entry.
> */
> - rcu_read_lock_bh();
> + rcu_read_lock();
> sequence = read_seqbegin(&base->lock);
> - p = lookup_rcu_bh(daddr, base);
> + p = lookup_rcu(daddr, base);
> invalidated = read_seqretry(&base->lock, sequence);
> - rcu_read_unlock_bh();
> + rcu_read_unlock();
>
> if (p) {
> /* The existing node has been found.
David, I am not sure this is safe, since we use call_rcu_bh() when
freeing one item. One cpu could decide to kfree() one item while another
cpu could still use it.
rcu_read_lock_bh() was signalling to others cpu we were in a softirq
section, so we were delaying a possible kfree().
^ permalink raw reply
* Re: ANNOUNCE: debloat-testing kernel git tree
From: Pavel Machek @ 2011-03-13 10:27 UTC (permalink / raw)
To: Rick Jones
Cc: Tianji Li, Dave T?ht, sedat.dilek, netdev, linux-wireless,
bloat-devel, linux-kernel
In-Reply-To: <1299610096.2087.8.camel@tardy>
Hi!
> > Bandwidth varies greatly with time. On cellphone, you can go from
> > 5KB/sec GPRS to 300KB/sec HSDPA and back...
>
> How quickly/often and does that trigger an event in the host that would
> allow adjustment of the queue?
I'd expect it to get fast when you leave the building, and back to
slow when you re-enter. It all depends how good 3G coverage is, but
seeing it change more than once a minute is not that uncommon.
Event... not sure. Linux can ask for current signal strength, and I
assume connection type works in similar way...
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Re: [PATCH 03/18] ipvs: zero percpu stats
From: Eric Dumazet @ 2011-03-13 10:57 UTC (permalink / raw)
To: Julian Anastasov
Cc: Simon Horman, netdev, netfilter-devel, netfilter, lvs-devel,
Hans Schillstrom
In-Reply-To: <alpine.LFD.2.00.1103061218470.1879@ja.ssi.bg>
Le dimanche 06 mars 2011 à 14:18 +0200, Julian Anastasov a écrit :
> Hello,
>
> On Sun, 6 Mar 2011, Eric Dumazet wrote:
>
> >> Zero the new percpu stats because we copy from there.
> >>
> >> Signed-off-by: Julian Anastasov <ja@ssi.bg>
> >> Signed-off-by: Simon Horman <horms@verge.net.au>
> >> ---
> >> net/netfilter/ipvs/ip_vs_ctl.c | 17 +++++++++++++++++
> >> 1 files changed, 17 insertions(+), 0 deletions(-)
> >>
> >> diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
> >> index a2a67ad..fd74527 100644
> >> --- a/net/netfilter/ipvs/ip_vs_ctl.c
> >> +++ b/net/netfilter/ipvs/ip_vs_ctl.c
> >> @@ -715,8 +715,25 @@ static void ip_vs_trash_cleanup(struct net *net)
> >> static void
> >> ip_vs_zero_stats(struct ip_vs_stats *stats)
> >> {
> >> + struct ip_vs_cpu_stats *cpustats = stats->cpustats;
> >> + int i;
> >> +
> >> spin_lock_bh(&stats->lock);
> >>
> >> + for_each_possible_cpu(i) {
> >> + struct ip_vs_cpu_stats *u = per_cpu_ptr(cpustats, i);
> >> + unsigned int start;
> >> +
> >> + /* Do not pretend to be writer, it is enough to
> >> + * sync with writers that modify the u64 counters
> >> + * because under stats->lock we are the only reader.
> >> + */
> >> + do {
> >> + start = u64_stats_fetch_begin(&u->syncp);
> >> + memset(&u->ustats, 0, sizeof(u->ustats));
> >> + } while (u64_stats_fetch_retry(&u->syncp, start));
> >
> >
> > Sorry this makes no sense to me.
>
> Hm, yes, the comment is a little bit misleading.
> I fixed it below...
>
> > This code _is_ a writer, and hardly a hot path.
>
> Yes, the picture is as follows:
>
> - in 2.6.38-rc we remove the global spin lock (stats->lock)
> from packet processing which is a hot path, adding percpu
> counters instead
>
> - we need protection for percpu counters and for the sum
>
> - the chain is: interrupts increment percpu counters, the
> estimation timer reads them and creates sum every 2 seconds,
> then user context can read the sum or even to show the percpu
> counters, not to forget the zeroing of sum and counters
>
> The players in detail:
>
> - packet processing:
> - softirq context, hot path
> - increments counters by using u64_stats_update_begin and
> u64_stats_update_end, does not wait readers or zeroing
> - sum not touched, stats->lock usage removed in 2.6.38-rc
>
> - 2-second estimation timer:
> - funcs: estimation_timer()
> - timer context, softirq
> - reads percpu counters with u64_stats_fetch_begin and
> u64_stats_fetch_retry to sync with counter incrementing
> - uses spin_lock (stats->lock) to protect the written sum
> which is later read by user context: provides
> at least u64 atomicity but additionally the relation
> between packets and bytes
>
> - sum readers:
> - funcs: ip_vs_stats_show(), ip_vs_stats_percpu_show(),
> ip_vs_copy_stats(), ip_vs_genl_fill_stats()
> - user context, not a hot path
> - uses spin_lock_bh (stats->lock) for atomic reading of
> the sum created by estimation_timer()
>
> - show percpu counters:
> - funcs: ip_vs_stats_percpu_show()
> - user context, not a hot path
> - uses u64_stats_fetch_begin_bh and u64_stats_fetch_retry_bh
> to synchronize with counter incrementing
> - still missing: should use spin_lock_bh (stats->lock)
> to synchronize with ip_vs_zero_stats() that modifies
> percpu counters.
>
> - zero stats and percpu counters
> - funcs: ip_vs_zero_stats()
> - user context, not a hot path
> - uses spin_lock_bh (stats->lock) while modifying
> sum but also while zeroing percpu counters because
> we are a hidden writer which does not allow other
> percpu counter readers at the same time but we are
> still synchronized with percpu counter incrementing
> without delaying it
>
> To summarize, I see 2 solutions, in order of preference:
>
> 1. all players except packet processing should use stats->lock
> when reading/writing sum or when reading/zeroing percpu
> counters. Use u64_stats to avoid delays in incrementing.
>
> 2. Use seqlock instead of u64_stats if we want to treat the
> percpu counters zeroing as writer. This returns us before
> 2.6.38-rc where we used global stats->lock even for counter
> incrementing. Except that now we can use percpu seqlock
> just to register the zeroing as writer.
>
> > Why try to pretend its a reader and confuse people ?
> >
> > Either :
> >
> > - Another writer can modify the counters in same time, and we must
> > synchronize with them (we are a writer after all)
>
> Global mutex allows only one zeroing at a time.
> But zeroing runs in parallel with incrementing, so we
> have 2 writers for a per-CPU state. This sounds like
> above solution 2 with percpu seqlock? But it adds extra
> spin_lock in hot path, even if it is percpu. It only
> saves the spin_lock_bh while reading percpu counters in
> ip_vs_stats_percpu_show(). That is why a prefer solution 1.
>
> > - Another reader can read the counters in same time, and we must let
> > them catch we mihjt have cleared half of their values.
>
> Yes, zeroing can run in parallel with /proc reading,
> that is why I now try to serialize all readers with the
> stats spin lock to guarantee u64 atomicity.
>
> > - No reader or writer can access data, no synch is needed, a pure
> > memset() is OK.
>
> Packet processing can damage the counters while we
> do memset, so we need at least u64_stats_fetch_* to sync
> with incrementing.
>
OK I now understand what you wanted to do.
Problem is you do synchronize your memset() with a concurrent writer but
one way only. (You detect a writer did some changes on the counters
while you memset() them), but a writer has no way to detect your writes
(could be partially committed to main memory) : It could read a
corrupted value.
I feel memory barriers are wrong and not really fixable without slowing
down the hot path.
As implied in include/linux/u64_stats_sync.h file, a "writer" should be
alone :)
One other way to handle that (and let hot path packet processing without
extra locking) would be to never memset() this data, but use a separate
"summed" value as a relative point, and substract this sum to the
current one (all this in slow path, so not a problem)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* (unknown),
From: Wang Lei @ 2011-03-13 8:03 UTC (permalink / raw)
I'm Wang Lei, I have a deal worth 25 Million USD if interested,
please contact
me via my personal email: wanglei99@w.cn
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
^ permalink raw reply
* hi
From: Vincent Appiah @ 2011-03-13 11:35 UTC (permalink / raw)
Attn: Please and a good day to you.
I have an important information for the owner of this email but first of all, I
want to ensure if this email is still valid, I want you to confirm if this email
is correct and is being checked by only you so that I will proceed and let you
know what information we have for you.
I am taking this measure in other not to make any mistake because of the
sensitivity of the information i have for you.
Awaiting your response.
Barr vincent Appiah.
^ permalink raw reply
* Hello
From: Johnson Ato @ 2011-03-13 12:50 UTC (permalink / raw)
--
Dear Friend,
I got your email address on the internet, I want you to assist
me by getting a nice property for purchase within your location
as me and my family wants to relocate to a safe environment as
soon as possible due to the crisis in my country.
Your urgent response is highly appreciated.
Johnson Ato
----------------------------------------------------------------
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox