Author: ae
Date: Wed Jan 24 12:40:28 2018
New Revision: 328326
URL: https://svnweb.freebsd.org/changeset/base/328326

Log:
  When IPv6 packet is handled by O_REJECT opcode, convert ICMP code
  specified in the arg1 into ICMPv6 destination unreachable code according
  to RFC7915.
  
  Obtained from:        Yandex LLC
  MFC after:    2 weeks
  Sponsored by: Yandex LLC

Modified:
  head/sys/netpfil/ipfw/ip_fw2.c

Modified: head/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw2.c      Wed Jan 24 12:01:32 2018        
(r328325)
+++ head/sys/netpfil/ipfw/ip_fw2.c      Wed Jan 24 12:40:28 2018        
(r328326)
@@ -821,6 +821,32 @@ is_icmp6_query(int icmp6_type)
        return (0);
 }
 
+static int
+map_icmp_unreach(int code)
+{
+
+       /* RFC 7915 p4.2 */
+       switch (code) {
+       case ICMP_UNREACH_NET:
+       case ICMP_UNREACH_HOST:
+       case ICMP_UNREACH_SRCFAIL:
+       case ICMP_UNREACH_NET_UNKNOWN:
+       case ICMP_UNREACH_HOST_UNKNOWN:
+       case ICMP_UNREACH_TOSNET:
+       case ICMP_UNREACH_TOSHOST:
+               return (ICMP6_DST_UNREACH_NOROUTE);
+       case ICMP_UNREACH_PORT:
+               return (ICMP6_DST_UNREACH_NOPORT);
+       default:
+               /*
+                * Map the rest of codes into admit prohibited.
+                * XXX: unreach proto should be mapped into ICMPv6
+                * parameter problem, but we use only unreach type.
+                */
+               return (ICMP6_DST_UNREACH_ADMIN);
+       }
+}
+
 static void
 send_reject6(struct ip_fw_args *args, int code, u_int hlen, struct ip6_hdr 
*ip6)
 {
@@ -2831,9 +2857,12 @@ do {                                                     
        \
                                    (proto != IPPROTO_ICMPV6 ||
                                     (is_icmp6_query(icmp6_type) == 1)) &&
                                    !(m->m_flags & (M_BCAST|M_MCAST)) &&
-                                   
!IN6_IS_ADDR_MULTICAST(&args->f_id.dst_ip6)) {
-                                       send_reject6(
-                                           args, cmd->arg1, hlen,
+                                   !IN6_IS_ADDR_MULTICAST(
+                                       &args->f_id.dst_ip6)) {
+                                       send_reject6(args,
+                                           cmd->opcode == O_REJECT ?
+                                           map_icmp_unreach(cmd->arg1):
+                                           cmd->arg1, hlen,
                                            (struct ip6_hdr *)ip);
                                        m = args->m;
                                }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to