- uh->uh_dport == ntohs((u_short)esp_udp_encap_port)) {
- int payload_len = ulen - sizeof (struct udphdr) > 4 ? 4 :
- ulen - sizeof (struct udphdr);
-
- if (m->m_len < off + sizeof (struct udphdr) + payload_len) {
- if ((m = m_pullup(m, off + sizeof (struct udphdr) +
- payload_len)) == NULL) {
- udpstat.udps_hdrops++;
+ (uh->uh_dport == ntohs((u_short)esp_udp_encap_port) ||
+ uh->uh_sport == ntohs((u_short)esp_udp_encap_port))) {
+ /*
+ * Check if ESP or keepalive:
+ * 1. If the destination port of the incoming packet is 4500.
+ * 2. If the source port of the incoming packet is 4500,
+ * then check the SADB to match IP address and port.
+ */
+ bool check_esp = true;
+ if (uh->uh_dport != ntohs((u_short)esp_udp_encap_port)) {
+ check_esp = key_checksa_present(AF_INET6, (caddr_t)&ip6->ip6_dst,
+ (caddr_t)&ip6->ip6_src, uh->uh_dport,
+ uh->uh_sport);
+ }
+
+ if (check_esp) {
+ int payload_len = ulen - sizeof(struct udphdr) > 4 ? 4 :
+ ulen - sizeof(struct udphdr);
+
+ if (m->m_len < off + sizeof(struct udphdr) + payload_len) {
+ if ((m = m_pullup(m, off + sizeof(struct udphdr) +
+ payload_len)) == NULL) {
+ udpstat.udps_hdrops++;
+ goto bad;
+ }
+ /*
+ * Expect 32-bit aligned data pointer on strict-align
+ * platforms.
+ */
+ MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
+
+ ip6 = mtod(m, struct ip6_hdr *);
+ uh = (struct udphdr *)(void *)((caddr_t)ip6 + off);
+ }
+ /* Check for NAT keepalive packet */
+ if (payload_len == 1 && *(u_int8_t*)
+ ((caddr_t)uh + sizeof(struct udphdr)) == 0xFF) {