Skip to content

Commit 366e41d

Browse files
vyasevichdavem330
authored andcommitted
ipv6: pull cork initialization into its own function.
Pull IPv6 cork initialization into its own function that can be re-used. IPv6 specific cork data did not have an explicit data structure. This patch creats eone so that just ipv6 cork data can be as arguemts. Also, since IPv6 tries to save the flow label into inet_cork_full tructure, pass the full cork. Adjust ip6_cork_release() to take cork data structures. Signed-off-by: Vladislav Yasevich <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ba0c39c commit 366e41d

File tree

2 files changed

+96
-74
lines changed

2 files changed

+96
-74
lines changed

include/linux/ipv6.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ struct ipv6_mc_socklist;
125125
struct ipv6_ac_socklist;
126126
struct ipv6_fl_socklist;
127127

128+
struct inet6_cork {
129+
struct ipv6_txoptions *opt;
130+
u8 hop_limit;
131+
u8 tclass;
132+
};
133+
128134
/**
129135
* struct ipv6_pinfo - ipv6 private area
130136
*
@@ -217,11 +223,7 @@ struct ipv6_pinfo {
217223
struct ipv6_txoptions *opt;
218224
struct sk_buff *pktoptions;
219225
struct sk_buff *rxpmtu;
220-
struct {
221-
struct ipv6_txoptions *opt;
222-
u8 hop_limit;
223-
u8 tclass;
224-
} cork;
226+
struct inet6_cork cork;
225227
};
226228

227229
/* WARNING: don't change the layout of the members in {raw,udp,tcp}6_sock! */

net/ipv6/ip6_output.c

Lines changed: 89 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,74 @@ static void ip6_append_data_mtu(unsigned int *mtu,
11351135
}
11361136
}
11371137

1138+
static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
1139+
struct inet6_cork *v6_cork,
1140+
int hlimit, int tclass, struct ipv6_txoptions *opt,
1141+
struct rt6_info *rt, struct flowi6 *fl6)
1142+
{
1143+
struct ipv6_pinfo *np = inet6_sk(sk);
1144+
unsigned int mtu;
1145+
1146+
/*
1147+
* setup for corking
1148+
*/
1149+
if (opt) {
1150+
if (WARN_ON(v6_cork->opt))
1151+
return -EINVAL;
1152+
1153+
v6_cork->opt = kzalloc(opt->tot_len, sk->sk_allocation);
1154+
if (unlikely(v6_cork->opt == NULL))
1155+
return -ENOBUFS;
1156+
1157+
v6_cork->opt->tot_len = opt->tot_len;
1158+
v6_cork->opt->opt_flen = opt->opt_flen;
1159+
v6_cork->opt->opt_nflen = opt->opt_nflen;
1160+
1161+
v6_cork->opt->dst0opt = ip6_opt_dup(opt->dst0opt,
1162+
sk->sk_allocation);
1163+
if (opt->dst0opt && !v6_cork->opt->dst0opt)
1164+
return -ENOBUFS;
1165+
1166+
v6_cork->opt->dst1opt = ip6_opt_dup(opt->dst1opt,
1167+
sk->sk_allocation);
1168+
if (opt->dst1opt && !v6_cork->opt->dst1opt)
1169+
return -ENOBUFS;
1170+
1171+
v6_cork->opt->hopopt = ip6_opt_dup(opt->hopopt,
1172+
sk->sk_allocation);
1173+
if (opt->hopopt && !v6_cork->opt->hopopt)
1174+
return -ENOBUFS;
1175+
1176+
v6_cork->opt->srcrt = ip6_rthdr_dup(opt->srcrt,
1177+
sk->sk_allocation);
1178+
if (opt->srcrt && !v6_cork->opt->srcrt)
1179+
return -ENOBUFS;
1180+
1181+
/* need source address above miyazawa*/
1182+
}
1183+
dst_hold(&rt->dst);
1184+
cork->base.dst = &rt->dst;
1185+
cork->fl.u.ip6 = *fl6;
1186+
v6_cork->hop_limit = hlimit;
1187+
v6_cork->tclass = tclass;
1188+
if (rt->dst.flags & DST_XFRM_TUNNEL)
1189+
mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1190+
rt->dst.dev->mtu : dst_mtu(&rt->dst);
1191+
else
1192+
mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1193+
rt->dst.dev->mtu : dst_mtu(rt->dst.path);
1194+
if (np->frag_size < mtu) {
1195+
if (np->frag_size)
1196+
mtu = np->frag_size;
1197+
}
1198+
cork->base.fragsize = mtu;
1199+
if (dst_allfrag(rt->dst.path))
1200+
cork->base.flags |= IPCORK_ALLFRAG;
1201+
cork->base.length = 0;
1202+
1203+
return 0;
1204+
}
1205+
11381206
int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
11391207
int offset, int len, int odd, struct sk_buff *skb),
11401208
void *from, int length, int transhdrlen,
@@ -1162,59 +1230,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
11621230
/*
11631231
* setup for corking
11641232
*/
1165-
if (opt) {
1166-
if (WARN_ON(np->cork.opt))
1167-
return -EINVAL;
1168-
1169-
np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation);
1170-
if (unlikely(np->cork.opt == NULL))
1171-
return -ENOBUFS;
1172-
1173-
np->cork.opt->tot_len = opt->tot_len;
1174-
np->cork.opt->opt_flen = opt->opt_flen;
1175-
np->cork.opt->opt_nflen = opt->opt_nflen;
1176-
1177-
np->cork.opt->dst0opt = ip6_opt_dup(opt->dst0opt,
1178-
sk->sk_allocation);
1179-
if (opt->dst0opt && !np->cork.opt->dst0opt)
1180-
return -ENOBUFS;
1181-
1182-
np->cork.opt->dst1opt = ip6_opt_dup(opt->dst1opt,
1183-
sk->sk_allocation);
1184-
if (opt->dst1opt && !np->cork.opt->dst1opt)
1185-
return -ENOBUFS;
1186-
1187-
np->cork.opt->hopopt = ip6_opt_dup(opt->hopopt,
1188-
sk->sk_allocation);
1189-
if (opt->hopopt && !np->cork.opt->hopopt)
1190-
return -ENOBUFS;
1191-
1192-
np->cork.opt->srcrt = ip6_rthdr_dup(opt->srcrt,
1193-
sk->sk_allocation);
1194-
if (opt->srcrt && !np->cork.opt->srcrt)
1195-
return -ENOBUFS;
1196-
1197-
/* need source address above miyazawa*/
1198-
}
1199-
dst_hold(&rt->dst);
1200-
cork->dst = &rt->dst;
1201-
inet->cork.fl.u.ip6 = *fl6;
1202-
np->cork.hop_limit = hlimit;
1203-
np->cork.tclass = tclass;
1204-
if (rt->dst.flags & DST_XFRM_TUNNEL)
1205-
mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1206-
rt->dst.dev->mtu : dst_mtu(&rt->dst);
1207-
else
1208-
mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1209-
rt->dst.dev->mtu : dst_mtu(rt->dst.path);
1210-
if (np->frag_size < mtu) {
1211-
if (np->frag_size)
1212-
mtu = np->frag_size;
1213-
}
1214-
cork->fragsize = mtu;
1215-
if (dst_allfrag(rt->dst.path))
1216-
cork->flags |= IPCORK_ALLFRAG;
1217-
cork->length = 0;
1233+
err = ip6_setup_cork(sk, &inet->cork, &np->cork, hlimit,
1234+
tclass, opt, rt, fl6);
1235+
if (err)
1236+
return err;
12181237
exthdrlen = (opt ? opt->opt_flen : 0);
12191238
length += exthdrlen;
12201239
transhdrlen += exthdrlen;
@@ -1226,8 +1245,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
12261245
transhdrlen = 0;
12271246
exthdrlen = 0;
12281247
dst_exthdrlen = 0;
1229-
mtu = cork->fragsize;
12301248
}
1249+
mtu = cork->fragsize;
12311250
orig_mtu = mtu;
12321251

12331252
hh_len = LL_RESERVED_SPACE(rt->dst.dev);
@@ -1503,23 +1522,24 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
15031522
}
15041523
EXPORT_SYMBOL_GPL(ip6_append_data);
15051524

1506-
static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np)
1525+
static void ip6_cork_release(struct inet_cork_full *cork,
1526+
struct inet6_cork *v6_cork)
15071527
{
1508-
if (np->cork.opt) {
1509-
kfree(np->cork.opt->dst0opt);
1510-
kfree(np->cork.opt->dst1opt);
1511-
kfree(np->cork.opt->hopopt);
1512-
kfree(np->cork.opt->srcrt);
1513-
kfree(np->cork.opt);
1514-
np->cork.opt = NULL;
1528+
if (v6_cork->opt) {
1529+
kfree(v6_cork->opt->dst0opt);
1530+
kfree(v6_cork->opt->dst1opt);
1531+
kfree(v6_cork->opt->hopopt);
1532+
kfree(v6_cork->opt->srcrt);
1533+
kfree(v6_cork->opt);
1534+
v6_cork->opt = NULL;
15151535
}
15161536

1517-
if (inet->cork.base.dst) {
1518-
dst_release(inet->cork.base.dst);
1519-
inet->cork.base.dst = NULL;
1520-
inet->cork.base.flags &= ~IPCORK_ALLFRAG;
1537+
if (cork->base.dst) {
1538+
dst_release(cork->base.dst);
1539+
cork->base.dst = NULL;
1540+
cork->base.flags &= ~IPCORK_ALLFRAG;
15211541
}
1522-
memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
1542+
memset(&cork->fl, 0, sizeof(cork->fl));
15231543
}
15241544

15251545
int ip6_push_pending_frames(struct sock *sk)
@@ -1599,7 +1619,7 @@ int ip6_push_pending_frames(struct sock *sk)
15991619
}
16001620

16011621
out:
1602-
ip6_cork_release(inet, np);
1622+
ip6_cork_release(&inet->cork, &np->cork);
16031623
return err;
16041624
error:
16051625
IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
@@ -1618,6 +1638,6 @@ void ip6_flush_pending_frames(struct sock *sk)
16181638
kfree_skb(skb);
16191639
}
16201640

1621-
ip6_cork_release(inet_sk(sk), inet6_sk(sk));
1641+
ip6_cork_release(&inet_sk(sk)->cork, &inet6_sk(sk)->cork);
16221642
}
16231643
EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);

0 commit comments

Comments
 (0)