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

Commit 93b36cf3 authored by Hannes Frederic Sowa's avatar Hannes Frederic Sowa Committed by David S. Miller
Browse files

ipv6: support IPV6_PMTU_INTERFACE on sockets



IPV6_PMTU_INTERFACE is the same as IPV6_PMTU_PROBE for ipv6. Add it
nontheless for symmetry with IPv4 sockets. Also drop incoming MTU
information if this mode is enabled.

The additional bit in ipv6_pinfo just eats in the padding behind the
bitfield. There are no changes to the layout of the struct at all.

Signed-off-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cd174e67
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ struct ipv6_pinfo {
	/* sockopt flags */
	__u16			recverr:1,
	                        sndflow:1,
				pmtudisc:2,
				pmtudisc:3,
				ipv6only:1,
				srcprefs:3,	/* 001: prefer temporary address
						 * 010: prefer public address
+6 −1
Original line number Diff line number Diff line
@@ -178,10 +178,15 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
{
	struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;

	return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
	return (np && np->pmtudisc >= IPV6_PMTUDISC_PROBE) ?
	       skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
}

static inline bool ip6_sk_accept_pmtu(const struct sock *sk)
{
	return inet6_sk(sk)->pmtudisc != IPV6_PMTUDISC_INTERFACE;
}

static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt)
{
	return &rt->rt6i_gateway;
+4 −0
Original line number Diff line number Diff line
@@ -188,6 +188,10 @@ enum {
#define IPV6_PMTUDISC_WANT		1
#define IPV6_PMTUDISC_DO		2
#define IPV6_PMTUDISC_PROBE		3
/* same as IPV6_PMTUDISC_PROBE, provided for symetry with IPv4
 * also see comments on IP_PMTUDISC_INTERFACE
 */
#define IPV6_PMTUDISC_INTERFACE		4

/* Flowlabel */
#define IPV6_FLOWLABEL_MGR	32
+3 −0
Original line number Diff line number Diff line
@@ -141,6 +141,9 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
	if (type == ICMPV6_PKT_TOOBIG) {
		struct dst_entry *dst = NULL;

		if (!ip6_sk_accept_pmtu(sk))
			goto out;

		if (sock_owned_by_user(sk))
			goto out;
		if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED))
+3 −3
Original line number Diff line number Diff line
@@ -1165,10 +1165,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
		np->cork.hop_limit = hlimit;
		np->cork.tclass = tclass;
		if (rt->dst.flags & DST_XFRM_TUNNEL)
			mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ?
			mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
			      rt->dst.dev->mtu : dst_mtu(&rt->dst);
		else
			mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ?
			mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
			      rt->dst.dev->mtu : dst_mtu(rt->dst.path);
		if (np->frag_size < mtu) {
			if (np->frag_size)
@@ -1270,7 +1270,7 @@ alloc_new_skb:
			if (skb == NULL || skb_prev == NULL)
				ip6_append_data_mtu(&mtu, &maxfraglen,
						    fragheaderlen, skb, rt,
						    np->pmtudisc ==
						    np->pmtudisc >=
						    IPV6_PMTUDISC_PROBE);

			skb_prev = skb;
Loading