Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 224829
b: refs/heads/master
c: defb351
h: refs/heads/master
i:
  224827: b3d2df7
v: v3
  • Loading branch information
David S. Miller committed Dec 9, 2010
1 parent cf1f221 commit cd07b05
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 82 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 84b3cdc38cd2882d7ac3c2ae4b6faf5c199874e3
refs/heads/master: defb3519a64141608725e2dac5a5aa9a3c644bae
26 changes: 23 additions & 3 deletions trunk/include/net/dst.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ struct dst_entry {

struct dst_ops *ops;

u32 metrics[RTAX_MAX];
u32 _metrics[RTAX_MAX];

#ifdef CONFIG_NET_CLS_ROUTE
__u32 tclassid;
Expand Down Expand Up @@ -106,7 +106,27 @@ struct dst_entry {
static inline u32
dst_metric(const struct dst_entry *dst, int metric)
{
return dst->metrics[metric-1];
return dst->_metrics[metric-1];
}

static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val)
{
dst->_metrics[metric-1] = val;
}

static inline void dst_import_metrics(struct dst_entry *dst, const u32 *src_metrics)
{
memcpy(dst->_metrics, src_metrics, RTAX_MAX * sizeof(u32));
}

static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_entry *src)
{
dst_import_metrics(dest, src->_metrics);
}

static inline u32 *dst_metrics_ptr(struct dst_entry *dst)
{
return dst->_metrics;
}

static inline u32
Expand Down Expand Up @@ -134,7 +154,7 @@ static inline unsigned long dst_metric_rtt(const struct dst_entry *dst, int metr
static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric,
unsigned long rtt)
{
dst->metrics[metric-1] = jiffies_to_msecs(rtt);
dst_metric_set(dst, metric, jiffies_to_msecs(rtt));
}

static inline u32
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/bridge/br_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)

#ifdef CONFIG_BRIDGE_NETFILTER
/* remember the MTU in the rtable for PMTU */
br->fake_rtable.dst.metrics[RTAX_MTU - 1] = new_mtu;
dst_metric_set(&br->fake_rtable.dst, RTAX_MTU, new_mtu);
#endif

return 0;
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/bridge/br_netfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ void br_netfilter_rtable_init(struct net_bridge *br)
atomic_set(&rt->dst.__refcnt, 1);
rt->dst.dev = br->dev;
rt->dst.path = &rt->dst;
rt->dst.metrics[RTAX_MTU - 1] = 1500;
dst_metric_set(&rt->dst, RTAX_MTU, 1500);
rt->dst.flags = DST_NOXFRM;
rt->dst.ops = &fake_dst_ops;
}
Expand Down
13 changes: 6 additions & 7 deletions trunk/net/decnet/dn_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,13 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)

if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) {
if (!(dst_metric_locked(dst, RTAX_MTU))) {
dst->metrics[RTAX_MTU-1] = mtu;
dst_metric_set(dst, RTAX_MTU, mtu);
dst_set_expires(dst, dn_rt_mtu_expires);
}
if (!(dst_metric_locked(dst, RTAX_ADVMSS))) {
u32 mss = mtu - DN_MAX_NSP_DATA_HEADER;
if (dst_metric(dst, RTAX_ADVMSS) > mss)
dst->metrics[RTAX_ADVMSS-1] = mss;
dst_metric_set(dst, RTAX_ADVMSS, mss);
}
}
}
Expand Down Expand Up @@ -806,8 +806,7 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
if (DN_FIB_RES_GW(*res) &&
DN_FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
rt->rt_gateway = DN_FIB_RES_GW(*res);
memcpy(rt->dst.metrics, fi->fib_metrics,
sizeof(rt->dst.metrics));
dst_import_metrics(&rt->dst, fi->fib_metrics);
}
rt->rt_type = res->type;

Expand All @@ -820,11 +819,11 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)

if (dst_metric(&rt->dst, RTAX_MTU) == 0 ||
dst_metric(&rt->dst, RTAX_MTU) > rt->dst.dev->mtu)
rt->dst.metrics[RTAX_MTU-1] = rt->dst.dev->mtu;
dst_metric_set(&rt->dst, RTAX_MTU, rt->dst.dev->mtu);
mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->dst));
if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0 ||
dst_metric(&rt->dst, RTAX_ADVMSS) > mss)
rt->dst.metrics[RTAX_ADVMSS-1] = mss;
dst_metric_set(&rt->dst, RTAX_ADVMSS, mss);
return 0;
}

Expand Down Expand Up @@ -1502,7 +1501,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
RTA_PUT(skb, RTA_PREFSRC, 2, &rt->rt_local_src);
if (rt->rt_daddr != rt->rt_gateway)
RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway);
if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0)
if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
goto rtattr_failure;
expires = rt->dst.expires ? rt->dst.expires - jiffies : 0;
if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires,
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv4/ip_gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
!ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
rt6->rt6i_dst.plen == 128) {
rt6->rt6i_flags |= RTF_MODIFIED;
skb_dst(skb)->metrics[RTAX_MTU-1] = mtu;
dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
}
}

Expand Down
55 changes: 30 additions & 25 deletions trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -1686,11 +1686,14 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
if (mtu < dst_mtu(&rth->dst)) {
dst_confirm(&rth->dst);
if (mtu < ip_rt_min_pmtu) {
u32 lock = dst_metric(&rth->dst,
RTAX_LOCK);
mtu = ip_rt_min_pmtu;
rth->dst.metrics[RTAX_LOCK-1] |=
(1 << RTAX_MTU);
lock |= (1 << RTAX_MTU);
dst_metric_set(&rth->dst, RTAX_LOCK,
lock);
}
rth->dst.metrics[RTAX_MTU-1] = mtu;
dst_metric_set(&rth->dst, RTAX_MTU, mtu);
dst_set_expires(&rth->dst,
ip_rt_mtu_expires);
}
Expand All @@ -1708,10 +1711,11 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
if (dst_mtu(dst) > mtu && mtu >= 68 &&
!(dst_metric_locked(dst, RTAX_MTU))) {
if (mtu < ip_rt_min_pmtu) {
u32 lock = dst_metric(dst, RTAX_LOCK);
mtu = ip_rt_min_pmtu;
dst->metrics[RTAX_LOCK-1] |= (1 << RTAX_MTU);
dst_metric_set(dst, RTAX_LOCK, lock | (1 << RTAX_MTU));
}
dst->metrics[RTAX_MTU-1] = mtu;
dst_metric_set(dst, RTAX_MTU, mtu);
dst_set_expires(dst, ip_rt_mtu_expires);
call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
}
Expand Down Expand Up @@ -1796,36 +1800,37 @@ static void set_class_tag(struct rtable *rt, u32 tag)

static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
{
struct dst_entry *dst = &rt->dst;
struct fib_info *fi = res->fi;

if (fi) {
if (FIB_RES_GW(*res) &&
FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
rt->rt_gateway = FIB_RES_GW(*res);
memcpy(rt->dst.metrics, fi->fib_metrics,
sizeof(rt->dst.metrics));
dst_import_metrics(dst, fi->fib_metrics);
if (fi->fib_mtu == 0) {
rt->dst.metrics[RTAX_MTU-1] = rt->dst.dev->mtu;
if (dst_metric_locked(&rt->dst, RTAX_MTU) &&
dst_metric_set(dst, RTAX_MTU, dst->dev->mtu);
if (dst_metric_locked(dst, RTAX_MTU) &&
rt->rt_gateway != rt->rt_dst &&
rt->dst.dev->mtu > 576)
rt->dst.metrics[RTAX_MTU-1] = 576;
dst->dev->mtu > 576)
dst_metric_set(dst, RTAX_MTU, 576);
}
#ifdef CONFIG_NET_CLS_ROUTE
rt->dst.tclassid = FIB_RES_NH(*res).nh_tclassid;
dst->tclassid = FIB_RES_NH(*res).nh_tclassid;
#endif
} else
rt->dst.metrics[RTAX_MTU-1]= rt->dst.dev->mtu;

if (dst_metric(&rt->dst, RTAX_HOPLIMIT) == 0)
rt->dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl;
if (dst_mtu(&rt->dst) > IP_MAX_MTU)
rt->dst.metrics[RTAX_MTU-1] = IP_MAX_MTU;
if (dst_metric(&rt->dst, RTAX_ADVMSS) == 0)
rt->dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, rt->dst.dev->mtu - 40,
ip_rt_min_advmss);
if (dst_metric(&rt->dst, RTAX_ADVMSS) > 65535 - 40)
rt->dst.metrics[RTAX_ADVMSS-1] = 65535 - 40;
dst_metric_set(dst, RTAX_MTU, dst->dev->mtu);

if (dst_metric(dst, RTAX_HOPLIMIT) == 0)
dst_metric_set(dst, RTAX_HOPLIMIT, sysctl_ip_default_ttl);
if (dst_mtu(dst) > IP_MAX_MTU)
dst_metric_set(dst, RTAX_MTU, IP_MAX_MTU);
if (dst_metric(dst, RTAX_ADVMSS) == 0)
dst_metric_set(dst, RTAX_ADVMSS,
max_t(unsigned int, dst->dev->mtu - 40,
ip_rt_min_advmss));
if (dst_metric(dst, RTAX_ADVMSS) > 65535 - 40)
dst_metric_set(dst, RTAX_ADVMSS, 65535 - 40);

#ifdef CONFIG_NET_CLS_ROUTE
#ifdef CONFIG_IP_MULTIPLE_TABLES
Expand Down Expand Up @@ -2720,7 +2725,7 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi
new->__use = 1;
new->input = dst_discard;
new->output = dst_discard;
memcpy(new->metrics, ort->dst.metrics, RTAX_MAX*sizeof(u32));
dst_copy_metrics(new, &ort->dst);

new->dev = ort->dst.dev;
if (new->dev)
Expand Down Expand Up @@ -2827,7 +2832,7 @@ static int rt_fill_info(struct net *net,
if (rt->rt_dst != rt->rt_gateway)
NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway);

if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0)
if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
goto nla_put_failure;

if (rt->fl.mark)
Expand Down
22 changes: 13 additions & 9 deletions trunk/net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ void tcp_update_metrics(struct sock *sk)
* Reset our results.
*/
if (!(dst_metric_locked(dst, RTAX_RTT)))
dst->metrics[RTAX_RTT - 1] = 0;
dst_metric_set(dst, RTAX_RTT, 0);
return;
}

Expand Down Expand Up @@ -776,34 +776,38 @@ void tcp_update_metrics(struct sock *sk)
if (dst_metric(dst, RTAX_SSTHRESH) &&
!dst_metric_locked(dst, RTAX_SSTHRESH) &&
(tp->snd_cwnd >> 1) > dst_metric(dst, RTAX_SSTHRESH))
dst->metrics[RTAX_SSTHRESH-1] = tp->snd_cwnd >> 1;
dst_metric_set(dst, RTAX_SSTHRESH, tp->snd_cwnd >> 1);
if (!dst_metric_locked(dst, RTAX_CWND) &&
tp->snd_cwnd > dst_metric(dst, RTAX_CWND))
dst->metrics[RTAX_CWND - 1] = tp->snd_cwnd;
dst_metric_set(dst, RTAX_CWND, tp->snd_cwnd);
} else if (tp->snd_cwnd > tp->snd_ssthresh &&
icsk->icsk_ca_state == TCP_CA_Open) {
/* Cong. avoidance phase, cwnd is reliable. */
if (!dst_metric_locked(dst, RTAX_SSTHRESH))
dst->metrics[RTAX_SSTHRESH-1] =
max(tp->snd_cwnd >> 1, tp->snd_ssthresh);
dst_metric_set(dst, RTAX_SSTHRESH,
max(tp->snd_cwnd >> 1, tp->snd_ssthresh));
if (!dst_metric_locked(dst, RTAX_CWND))
dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_cwnd) >> 1;
dst_metric_set(dst, RTAX_CWND,
(dst_metric(dst, RTAX_CWND) +
tp->snd_cwnd) >> 1);
} else {
/* Else slow start did not finish, cwnd is non-sense,
ssthresh may be also invalid.
*/
if (!dst_metric_locked(dst, RTAX_CWND))
dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_ssthresh) >> 1;
dst_metric_set(dst, RTAX_CWND,
(dst_metric(dst, RTAX_CWND) +
tp->snd_ssthresh) >> 1);
if (dst_metric(dst, RTAX_SSTHRESH) &&
!dst_metric_locked(dst, RTAX_SSTHRESH) &&
tp->snd_ssthresh > dst_metric(dst, RTAX_SSTHRESH))
dst->metrics[RTAX_SSTHRESH-1] = tp->snd_ssthresh;
dst_metric_set(dst, RTAX_SSTHRESH, tp->snd_ssthresh);
}

if (!dst_metric_locked(dst, RTAX_REORDERING)) {
if (dst_metric(dst, RTAX_REORDERING) < tp->reordering &&
tp->reordering != sysctl_tcp_reordering)
dst->metrics[RTAX_REORDERING-1] = tp->reordering;
dst_metric_set(dst, RTAX_REORDERING, tp->reordering);
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions trunk/net/ipv6/ndisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
if (ra_msg->icmph.icmp6_hop_limit) {
in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
if (rt)
rt->dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit;
dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
ra_msg->icmph.icmp6_hop_limit);
}

skip_defrtr:
Expand Down Expand Up @@ -1377,7 +1378,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
in6_dev->cnf.mtu6 = mtu;

if (rt)
rt->dst.metrics[RTAX_MTU-1] = mtu;
dst_metric_set(&rt->dst, RTAX_MTU, mtu);

rt6_mtu_change(skb->dev, mtu);
}
Expand Down
Loading

0 comments on commit cd07b05

Please sign in to comment.