On 04/11/16(Fri) 21:33, Vincent Gross wrote:
> [...] 
> Why are you killing Strict Source Route Record ? Just as you did with
> rtredirect(), you can check whether RTF_GATEWAY is set and send back
> an ICMP_UNREACH if so. Or did I miss something ?

Like that?

Index: netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.282
diff -u -p -r1.282 ip_input.c
--- netinet/ip_input.c  22 Sep 2016 10:12:25 -0000      1.282
+++ netinet/ip_input.c  7 Nov 2016 07:59:02 -0000
@@ -1117,37 +1117,20 @@ ip_dooptions(struct mbuf *m, struct ifne
                        ipaddr.sin_len = sizeof(ipaddr);
                        memcpy(&ipaddr.sin_addr, cp + off,
                            sizeof(ipaddr.sin_addr));
-                       if (opt == IPOPT_SSRR) {
-                               if ((ia = ifatoia(ifa_ifwithdstaddr(
-                                   sintosa(&ipaddr),
-                                   m->m_pkthdr.ph_rtableid))) == NULL)
-                                       ia = ifatoia(ifa_ifwithnet(
-                                           sintosa(&ipaddr),
-                                           m->m_pkthdr.ph_rtableid));
-                               if (ia == NULL) {
-                                       type = ICMP_UNREACH;
-                                       code = ICMP_UNREACH_SRCFAIL;
-                                       goto bad;
-                               }
-                               memcpy(cp + off, &ia->ia_addr.sin_addr,
-                                   sizeof(struct in_addr));
-                               cp[IPOPT_OFFSET] += sizeof(struct in_addr);
-                       } else {
-                               /* keep packet in the virtual instance */
-                               rt = rtalloc(sintosa(&ipaddr), RT_RESOLVE,
-                                   rtableid);
-                               if (!rtisvalid(rt)) {
-                                       type = ICMP_UNREACH;
-                                       code = ICMP_UNREACH_SRCFAIL;
-                                       rtfree(rt);
-                                       goto bad;
-                               }
-                               ia = ifatoia(rt->rt_ifa);
-                               memcpy(cp + off, &ia->ia_addr.sin_addr,
-                                   sizeof(struct in_addr));
+                       /* keep packet in the virtual instance */
+                       rt = rtalloc(sintosa(&ipaddr), RT_RESOLVE, rtableid);
+                       if (!rtisvalid(rt) || ((opt == IPOPT_SSRR) &&
+                           ISSET(rt->rt_flags, RTF_GATEWAY))) {
+                               type = ICMP_UNREACH;
+                               code = ICMP_UNREACH_SRCFAIL;
                                rtfree(rt);
-                               cp[IPOPT_OFFSET] += sizeof(struct in_addr);
+                               goto bad;
                        }
+                       ia = ifatoia(rt->rt_ifa);
+                       memcpy(cp + off, &ia->ia_addr.sin_addr,
+                           sizeof(struct in_addr));
+                       rtfree(rt);
+                       cp[IPOPT_OFFSET] += sizeof(struct in_addr);
                        ip->ip_dst = ipaddr.sin_addr;
                        /*
                         * Let ip_intr's mcast routing check handle mcast pkts

Reply via email to