Index: sys/netinet/ip.h =================================================================== RCS file: /cvs/src/sys/netinet/ip.h,v retrieving revision 1.13 diff -u -p -r1.13 ip.h --- sys/netinet/ip.h 27 Jul 2009 12:52:42 -0000 1.13 +++ sys/netinet/ip.h 12 Dec 2012 05:50:49 -0000 @@ -150,6 +150,7 @@ struct ip { #define IPOPT_LSRR 131 /* loose source route */ #define IPOPT_SATID 136 /* satnet id */ #define IPOPT_SSRR 137 /* strict source route */ +#define IPOPT_RA 148 /* router alert */ /* * Offsets to fields in options other than EOL and NOP. Index: sys/netinet/ip_output.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_output.c,v retrieving revision 1.235 diff -u -p -r1.235 ip_output.c --- sys/netinet/ip_output.c 6 Nov 2012 12:32:42 -0000 1.235 +++ sys/netinet/ip_output.c 12 Dec 2012 05:50:50 -0000 @@ -376,7 +376,8 @@ reroute: * destination and is still up. If not, free it and try again. */ if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || - dst->sin_addr.s_addr != ip->ip_dst.s_addr || + (dst->sin_addr.s_addr != ip->ip_dst.s_addr && + (flags & IP_RAWOUTPUT) == 0) || ro->ro_tableid != m->m_pkthdr.rdomain)) { RTFREE(ro->ro_rt); ro->ro_rt = (struct rtentry *)0; Index: sys/netinet/raw_ip.c =================================================================== RCS file: /cvs/src/sys/netinet/raw_ip.c,v retrieving revision 1.62 diff -u -p -r1.62 raw_ip.c --- sys/netinet/raw_ip.c 21 Oct 2012 13:06:03 -0000 1.62 +++ sys/netinet/raw_ip.c 12 Dec 2012 05:50:50 -0000 @@ -208,6 +208,7 @@ rip_output(struct mbuf *m, ...) struct socket *so; u_long dst; struct ip *ip; + struct sockaddr_in *dstip; struct inpcb *inp; int flags, error; va_list ap; @@ -266,6 +267,21 @@ rip_output(struct mbuf *m, ...) /* XXX prevent ip_output from overwriting header fields */ flags |= IP_RAWOUTPUT; ipstat.ips_rawout++; + + /*** XXX: + * if user provided dst address - IGNORE the one from packet + * and do a routing lookup, ip_output will send the packet + * out correct interface, possibly with correct MPLS label + */ + if (dst != INADDR_ANY && !IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) + && dst != ip->ip_dst.s_addr) { + dstip = satosin(&inp->inp_route.ro_dst); + dstip->sin_family = AF_INET; + dstip->sin_len = sizeof(*dstip); + dstip->sin_addr.s_addr = dst; + inp->inp_route.ro_tableid = m->m_pkthdr.rdomain; + rtalloc_mpath(&inp->inp_route, NULL); + } } #ifdef INET6 /*