On 07/08/16 23:35, Alexander Bluhm wrote:
> On Tue, Jun 28, 2016 at 08:30:16AM +0200, Martin Pieuchot wrote:
>> With this diff if your next hop becomes invalid after being cached you'll
>> also need two ICMP6_PACKET_TOO_BIG to restore the MTU, is this wanted?
> 
> No, a single ICMP6_PACKET_TOO_BIG packet is enough.  I have written
> a test that checks all cases.
> 
> https://github.com/bluhm/pmtu-regress
> 
> After the issue has been fixed, I would like to commit it to
> /usr/src/regress/sys/netinet/pmtu .

ok mpi@

>> I would prefer if we could cache the gw route in a single place.  So
>> I'm wondering if the check for reseting PMTUD makes sense (where it is).
> 
> After testing TCP, TCP6, UDP6 I still think my diff is correct.  It
> makes sense to reset the PMTU discovery after the gateway route is
> gone.
> 
> I the current implementation rtalloc() returns a route with a valid
> gateway, while rtrequest(RTM_ADD) returns a route with an invalid
> gateway.  I think both methods should provide a similar route, so
> rt_setgwroute() should fix the gateway route in both functions.

I'm convinced, ok mpi@

>>> Index: net/if_spppsubr.c
>>> ===================================================================
>>> RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_spppsubr.c,v
>>> retrieving revision 1.154
>>> diff -u -p -r1.154 if_spppsubr.c
>>> --- net/if_spppsubr.c       14 Jun 2016 20:44:43 -0000      1.154
>>> +++ net/if_spppsubr.c       24 Jun 2016 22:32:28 -0000
>>> @@ -4161,7 +4161,7 @@ sppp_update_gw_walker(struct rtentry *rt
>>>                 rt->rt_gateway->sa_family ||
>>>                 !ISSET(rt->rt_flags, RTF_GATEWAY))
>>>                     return (0);     /* do not modify non-gateway routes */
>>> -           rt_setgate(rt, rt->rt_ifa->ifa_dstaddr);
>>> +           rt_setgate(rt, rt->rt_ifa->ifa_dstaddr, ifp->if_rdomain);
>>>     }
>>>     return (0);
>>>  }
>>> Index: net/route.c
>>> ===================================================================
>>> RCS file: /data/mirror/openbsd/cvs/src/sys/net/route.c,v
>>> retrieving revision 1.309
>>> diff -u -p -r1.309 route.c
>>> --- net/route.c     14 Jun 2016 09:48:52 -0000      1.309
>>> +++ net/route.c     24 Jun 2016 22:37:45 -0000
>>> @@ -154,6 +154,7 @@ struct pool             rttimer_pool;   /* pool for r
>>>  
>>>  void       rt_timer_init(void);
>>>  int        rt_setaddr(struct rtentry *, struct sockaddr *);
>>> +void       rt_setgwroute(struct rtentry *, u_int);
>>>  int        rtflushclone1(struct rtentry *, void *, u_int);
>>>  void       rtflushclone(unsigned int, struct rtentry *);
>>>  int        rt_if_remove_rtdelete(struct rtentry *, void *, u_int);
>>> @@ -369,7 +370,7 @@ rtalloc(struct sockaddr *dst, int flags,
>>>  struct rtentry *
>>>  _rtalloc(struct sockaddr *dst, uint32_t *src, int flags, unsigned int 
>>> rtableid)
>>>  {
>>> -   struct rtentry *rt, *nhrt;
>>> +   struct rtentry *rt;
>>>  
>>>     rt = rt_match(dst, src, flags, rtableid);
>>>  
>>> @@ -381,6 +382,16 @@ _rtalloc(struct sockaddr *dst, uint32_t 
>>>     if (rtisvalid(rt->rt_gwroute))
>>>             return (rt);
>>>  
>>> +   rt_setgwroute(rt, rtableid);
>>> +
>>> +   return (rt);
>>> +}
>>> +
>>> +void
>>> +rt_setgwroute(struct rtentry *rt, u_int rtableid)
>>> +{
>>> +   struct rtentry *nhrt;
>>> +
>>>     rtfree(rt->rt_gwroute);
>>>     rt->rt_gwroute = NULL;
>>>  
>>> @@ -392,10 +403,9 @@ _rtalloc(struct sockaddr *dst, uint32_t 
>>>      * this behavior.  But it is safe since rt_checkgate() wont
>>>      * allow us to us this route later on.
>>>      */
>>> -   nhrt = rt_match(rt->rt_gateway, NULL, flags | RT_RESOLVE,
>>> -       rtable_l2(rtableid));
>>> +   nhrt = rt_match(rt->rt_gateway, NULL, RT_RESOLVE, rtable_l2(rtableid));
>>>     if (nhrt == NULL)
>>> -           return (rt);
>>> +           return;
>>>  
>>>     /*
>>>      * Next hop must be reachable, this also prevents rtentry
>>> @@ -403,13 +413,13 @@ _rtalloc(struct sockaddr *dst, uint32_t 
>>>      */
>>>     if (ISSET(nhrt->rt_flags, RTF_CLONING|RTF_GATEWAY)) {
>>>             rtfree(nhrt);
>>> -           return (rt);
>>> +           return;
>>>     }
>>>  
>>>     /* Next hop entry must be UP and on the same interface. */
>>>     if (!ISSET(nhrt->rt_flags, RTF_UP) || nhrt->rt_ifidx != rt->rt_ifidx) {
>>>             rtfree(nhrt);
>>> -           return (rt);
>>> +           return;
>>>     }
>>>  
>>>     /*
>>> @@ -424,8 +434,6 @@ _rtalloc(struct sockaddr *dst, uint32_t 
>>>      * do the magic for us.
>>>      */
>>>     rt->rt_gwroute = nhrt;
>>> -
>>> -   return (rt);
>>>  }
>>>  
>>>  void
>>> @@ -595,7 +603,7 @@ create:
>>>                     flags |= RTF_MODIFIED;
>>>                     prio = rt->rt_priority;
>>>                     stat = &rtstat.rts_newgateway;
>>> -                   rt_setgate(rt, gateway);
>>> +                   rt_setgate(rt, gateway, rdomain);
>>>             }
>>>     } else
>>>             error = EHOSTUNREACH;
>>> @@ -1089,7 +1097,8 @@ rtrequest(int req, struct rt_addrinfo *i
>>>              * it to (re)order routes.
>>>              */
>>>             if ((error = rt_setaddr(rt, ifa->ifa_addr)) ||
>>> -               (error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY]))) {
>>> +               (error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY],
>>> +               tableid))) {
>>>                     ifafree(ifa);
>>>                     rtfree(rt->rt_parent);
>>>                     rtfree(rt->rt_gwroute);
>>> @@ -1169,7 +1178,7 @@ rt_setaddr(struct rtentry *rt, struct so
>>>  }
>>>  
>>>  int
>>> -rt_setgate(struct rtentry *rt, struct sockaddr *gate)
>>> +rt_setgate(struct rtentry *rt, struct sockaddr *gate, u_int rtableid)
>>>  {
>>>     int glen = ROUNDUP(gate->sa_len);
>>>     struct sockaddr *sa;
>>> @@ -1183,8 +1192,8 @@ rt_setgate(struct rtentry *rt, struct so
>>>     }
>>>     memmove(rt->rt_gateway, gate, glen);
>>>  
>>> -   rtfree(rt->rt_gwroute);
>>> -   rt->rt_gwroute = NULL;
>>> +   if (ISSET(rt->rt_flags, RTF_GATEWAY))
>>> +           rt_setgwroute(rt, rtableid);
>>>  
>>>     return (0);
>>>  }
>>> Index: net/route.h
>>> ===================================================================
>>> RCS file: /data/mirror/openbsd/cvs/src/sys/net/route.h,v
>>> retrieving revision 1.138
>>> diff -u -p -r1.138 route.h
>>> --- net/route.h     14 Jun 2016 09:48:52 -0000      1.138
>>> +++ net/route.h     24 Jun 2016 22:29:45 -0000
>>> @@ -363,7 +363,7 @@ struct sockaddr *rt_plen2mask(struct rte
>>>  void        rt_sendmsg(struct rtentry *, int, u_int);
>>>  void        rt_sendaddrmsg(struct rtentry *, int, struct ifaddr *);
>>>  void        rt_missmsg(int, struct rt_addrinfo *, int, uint8_t, u_int, 
>>> int, u_int);
>>> -int         rt_setgate(struct rtentry *, struct sockaddr *);
>>> +int         rt_setgate(struct rtentry *, struct sockaddr *, u_int);
>>>  int         rt_checkgate(struct rtentry *, struct rtentry **);
>>>  void        rt_setmetrics(u_long, const struct rt_metrics *, struct 
>>> rt_kmetrics *);
>>>  void        rt_getmetrics(const struct rt_kmetrics *, struct rt_metrics *);
>>> Index: net/rtsock.c
>>> ===================================================================
>>> RCS file: /data/mirror/openbsd/cvs/src/sys/net/rtsock.c,v
>>> retrieving revision 1.192
>>> diff -u -p -r1.192 rtsock.c
>>> --- net/rtsock.c    14 Jun 2016 09:48:52 -0000      1.192
>>> +++ net/rtsock.c    24 Jun 2016 22:33:04 -0000
>>> @@ -748,7 +748,8 @@ report:
>>>                             ifa = info.rti_ifa;
>>>                     }
>>>                     if (info.rti_info[RTAX_GATEWAY] != NULL && (error =
>>> -                       rt_setgate(rt, info.rti_info[RTAX_GATEWAY])))
>>> +                       rt_setgate(rt, info.rti_info[RTAX_GATEWAY],
>>> +                       tableid)))
>>>                             goto flush;
>>>                     if (ifa) {
>>>                             if (rt->rt_ifa != ifa) {
>>>
> 

Reply via email to