Diff below simplifies ip6_getpmtu() to use a 'struct rtentry *' instead
of two 'struct route_in6'.

ok?

Index: netinet6/ip6_output.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.212
diff -u -p -r1.212 ip6_output.c
--- netinet6/ip6_output.c       22 Aug 2016 10:33:22 -0000      1.212
+++ netinet6/ip6_output.c       24 Aug 2016 10:10:56 -0000
@@ -128,8 +128,7 @@ int ip6_insertfraghdr(struct mbuf *, str
        struct ip6_frag **);
 int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t);
 int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *);
-int ip6_getpmtu(struct route_in6 *, struct route_in6 *, struct ifnet *,
-    unsigned int, struct in6_addr *, u_long *, int *);
+int ip6_getpmtu(struct rtentry *, struct ifnet *, u_long *, int *);
 int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int);
 static __inline u_int16_t __attribute__((__unused__))
     in6_cksum_phdr(const struct in6_addr *, const struct in6_addr *,
@@ -558,8 +557,7 @@ reroute:
        }
 
        /* Determine path MTU. */
-       if ((error = ip6_getpmtu(ro_pmtu, ro, ifp, ro->ro_tableid, &finaldst,
-           &mtu, &alwaysfrag)) != 0)
+       if ((error = ip6_getpmtu(ro_pmtu->ro_rt, ifp, &mtu, &alwaysfrag)) != 0)
                goto bad;
 
        /*
@@ -1025,45 +1023,15 @@ ip6_insertfraghdr(struct mbuf *m0, struc
 }
 
 int
-ip6_getpmtu(struct route_in6 *ro_pmtu, struct route_in6 *ro, struct ifnet 
*ifp0,
-    unsigned int rtableid, struct in6_addr *dst, u_long *mtup, int 
*alwaysfragp)
+ip6_getpmtu(struct rtentry *rt, struct ifnet *ifp, u_long *mtup,
+    int *alwaysfragp)
 {
        u_int32_t mtu = 0;
        int alwaysfrag = 0;
        int error = 0;
 
-       if (ro_pmtu != ro) {
-               /* The first hop and the final destination may differ. */
-               struct sockaddr_in6 *sa6_dst = &ro_pmtu->ro_dst;
-
-               if (!rtisvalid(ro_pmtu->ro_rt) ||
-                   (ro_pmtu->ro_tableid != rtableid) ||
-                    !IN6_ARE_ADDR_EQUAL(&sa6_dst->sin6_addr, dst)) {
-                       rtfree(ro_pmtu->ro_rt);
-                       ro_pmtu->ro_rt = NULL;
-               }
-               if (ro_pmtu->ro_rt == NULL) {
-                       bzero(ro_pmtu, sizeof(*ro_pmtu));
-                       ro_pmtu->ro_tableid = rtableid;
-                       sa6_dst->sin6_family = AF_INET6;
-                       sa6_dst->sin6_len = sizeof(struct sockaddr_in6);
-                       sa6_dst->sin6_addr = *dst;
-
-                       ro_pmtu->ro_rt = rtalloc(sin6tosa(&ro_pmtu->ro_dst),
-                           RT_RESOLVE, ro_pmtu->ro_tableid);
-               }
-       }
-       if (ro_pmtu->ro_rt) {
-               struct ifnet *ifp;
-
-               if (ifp0 == NULL) {
-                       ifp = if_get(ro_pmtu->ro_rt->rt_ifidx);
-                       if (ifp == NULL)
-                               return (EHOSTUNREACH);
-               } else
-                       ifp = ifp0;
-
-               mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu;
+       if (rt != NULL) {
+               mtu = rt->rt_rmx.rmx_mtu;
                if (mtu == 0)
                        mtu = ifp->if_mtu;
                else if (mtu < IPV6_MMTU) {
@@ -1087,14 +1055,11 @@ ip6_getpmtu(struct route_in6 *ro_pmtu, s
                         * field isn't locked).
                         */
                        mtu = ifp->if_mtu;
-                       if (!(ro_pmtu->ro_rt->rt_rmx.rmx_locks & RTV_MTU))
-                               ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu;
+                       if (!(rt->rt_rmx.rmx_locks & RTV_MTU))
+                               rt->rt_rmx.rmx_mtu = mtu;
                }
-
-               if (ifp0 == NULL)
-                       if_put(ifp);
-       } else if (ifp0) {
-               mtu = ifp0->if_mtu;
+       } else if (ifp) {
+               mtu = ifp->if_mtu;
        } else
                error = EHOSTUNREACH; /* XXX */
 
@@ -1546,18 +1511,26 @@ do { \
                        {
                                u_long pmtu = 0;
                                struct ip6_mtuinfo mtuinfo;
-                               struct route_in6 *ro = (struct route_in6 
*)&inp->inp_route6;
+                               struct ifnet *ifp;
+                               struct rtentry *rt;
 
                                if (!(so->so_state & SS_ISCONNECTED))
                                        return (ENOTCONN);
+
+                               rt = in_pcbrtentry(inp);
+                               if (!rtisvalid(rt))
+                                       return (EHOSTUNREACH);
+
+                               ifp = if_get(rt->rt_ifidx);
+                               if (ifp == NULL)
+                                       return (EHOSTUNREACH);
                                /*
                                 * XXX: we dot not consider the case of source
                                 * routing, or optional information to specify
                                 * the outgoing interface.
                                 */
-                               error = ip6_getpmtu(ro, NULL, NULL,
-                                   inp->inp_rtableid, &inp->inp_faddr6, &pmtu,
-                                   NULL);
+                               error = ip6_getpmtu(rt, ifp, &pmtu, NULL);
+                               if_put(ifp);
                                if (error)
                                        break;
                                if (pmtu > IPV6_MAXPACKET)

Reply via email to