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