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