Author: ae
Date: Wed Jul 15 21:09:38 2015
New Revision: 285614
URL: https://svnweb.freebsd.org/changeset/base/285614

Log:
  MFC r285204:
    Fill the port and protocol information in the SADB_ACQUIRE message
    in case when security policy has it as required by RFC 2367.
  
    PR:         192774
  
  Approved by:  re (delphij)

Modified:
  stable/10/sys/netipsec/key.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/netipsec/key.c
==============================================================================
--- stable/10/sys/netipsec/key.c        Wed Jul 15 19:38:14 2015        
(r285613)
+++ stable/10/sys/netipsec/key.c        Wed Jul 15 21:09:38 2015        
(r285614)
@@ -6149,16 +6149,21 @@ key_getprop(const struct secasindex *sai
 static int
 key_acquire(const struct secasindex *saidx, struct secpolicy *sp)
 {
-       struct mbuf *result = NULL, *m;
+       union sockaddr_union addr;
+       struct mbuf *result, *m;
        struct secacq *newacq;
-       u_int8_t satype;
-       int error = -1;
        u_int32_t seq;
+       int error;
+       u_int16_t ul_proto;
+       u_int8_t mask, satype;
 
        IPSEC_ASSERT(saidx != NULL, ("null saidx"));
        satype = key_proto2satype(saidx->proto);
        IPSEC_ASSERT(satype != 0, ("null satype, protocol %u", saidx->proto));
 
+       error = -1;
+       result = NULL;
+       ul_proto = IPSEC_ULPROTO_ANY;
        /*
         * We never do anything about acquirng SA.  There is anather
         * solution that kernel blocks to send SADB_ACQUIRE message until
@@ -6195,17 +6200,64 @@ key_acquire(const struct secasindex *sai
         * anything related to NAT-T at this time.
         */
 
-       /* set sadb_address for saidx's. */
-       m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
-           &saidx->src.sa, FULLMASK, IPSEC_ULPROTO_ANY);
+       /*
+        * set sadb_address for saidx's.
+        *
+        * Note that if sp is supplied, then we're being called from
+        * key_checkrequest and should supply port and protocol information.
+        */
+       if (sp != NULL && (sp->spidx.ul_proto == IPPROTO_TCP ||
+           sp->spidx.ul_proto == IPPROTO_UDP))
+               ul_proto = sp->spidx.ul_proto;
+
+       addr = saidx->src;
+       mask = FULLMASK;
+       if (ul_proto != IPSEC_ULPROTO_ANY) {
+               switch (sp->spidx.src.sa.sa_family) {
+               case AF_INET:
+                       if (sp->spidx.src.sin.sin_port != IPSEC_PORT_ANY) {
+                               addr.sin.sin_port = sp->spidx.src.sin.sin_port;
+                               mask = sp->spidx.prefs;
+                       }
+                       break;
+               case AF_INET6:
+                       if (sp->spidx.src.sin6.sin6_port != IPSEC_PORT_ANY) {
+                               addr.sin6.sin6_port = 
sp->spidx.src.sin6.sin6_port;
+                               mask = sp->spidx.prefs;
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+       m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, &addr.sa, mask, ul_proto);
        if (!m) {
                error = ENOBUFS;
                goto fail;
        }
        m_cat(result, m);
 
-       m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
-           &saidx->dst.sa, FULLMASK, IPSEC_ULPROTO_ANY);
+       addr = saidx->dst;
+       mask = FULLMASK;
+       if (ul_proto != IPSEC_ULPROTO_ANY) {
+               switch (sp->spidx.dst.sa.sa_family) {
+               case AF_INET:
+                       if (sp->spidx.dst.sin.sin_port != IPSEC_PORT_ANY) {
+                               addr.sin.sin_port = sp->spidx.dst.sin.sin_port;
+                               mask = sp->spidx.prefd;
+                       }
+                       break;
+               case AF_INET6:
+                       if (sp->spidx.dst.sin6.sin6_port != IPSEC_PORT_ANY) {
+                               addr.sin6.sin6_port = 
sp->spidx.dst.sin6.sin6_port;
+                               mask = sp->spidx.prefd;
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+       m = key_setsadbaddr(SADB_EXT_ADDRESS_DST, &addr.sa, mask, ul_proto);
        if (!m) {
                error = ENOBUFS;
                goto fail;
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to