Attempt to improve feature parity between UDPv4 and UDPv6 by merging
UDPv4 features to UDPv6: - Add MAC checks on delivery and MAC labeling on transmit. - Check for (and reject) datagrams with destination port 0. - For multicast delivery, check the source port only if the socket being considered as a destination has been connected. - Implement UDP blackholing based on net.inet.udp.blackhole. - Add a new ICMPv6 unreachable reply rate limiting category for failed delivery attempts and implement rate limiting for UDPv6 (submitted by bz). Approved by: re (kensmith) Reviewed by: bz
This commit is contained in:
parent
6c9872b62a
commit
5fe56c549d
@ -82,7 +82,8 @@ extern int badport_bandlim(int);
|
|||||||
#define BANDLIM_ICMP_TSTAMP 2
|
#define BANDLIM_ICMP_TSTAMP 2
|
||||||
#define BANDLIM_RST_CLOSEDPORT 3 /* No connection, and no listeners */
|
#define BANDLIM_RST_CLOSEDPORT 3 /* No connection, and no listeners */
|
||||||
#define BANDLIM_RST_OPENPORT 4 /* No connection, listener */
|
#define BANDLIM_RST_OPENPORT 4 /* No connection, listener */
|
||||||
#define BANDLIM_MAX 4
|
#define BANDLIM_ICMP6_UNREACH 5
|
||||||
|
#define BANDLIM_MAX 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -888,7 +888,8 @@ badport_bandlim(int which)
|
|||||||
{ "icmp ping response" },
|
{ "icmp ping response" },
|
||||||
{ "icmp tstamp response" },
|
{ "icmp tstamp response" },
|
||||||
{ "closed port RST response" },
|
{ "closed port RST response" },
|
||||||
{ "open port RST response" }
|
{ "open port RST response" },
|
||||||
|
{ "icmp6 unreach response" }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
#include "opt_inet.h"
|
#include "opt_inet.h"
|
||||||
#include "opt_inet6.h"
|
#include "opt_inet6.h"
|
||||||
#include "opt_ipsec.h"
|
#include "opt_ipsec.h"
|
||||||
|
#include "opt_mac.h"
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
@ -92,7 +93,9 @@
|
|||||||
#include <netinet/in_systm.h>
|
#include <netinet/in_systm.h>
|
||||||
#include <netinet/in_var.h>
|
#include <netinet/in_var.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
|
#include <netinet/ip_icmp.h>
|
||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
|
#include <netinet/icmp_var.h>
|
||||||
#include <netinet/icmp6.h>
|
#include <netinet/icmp6.h>
|
||||||
#include <netinet/ip_var.h>
|
#include <netinet/ip_var.h>
|
||||||
#include <netinet/udp.h>
|
#include <netinet/udp.h>
|
||||||
@ -108,6 +111,8 @@
|
|||||||
#include <netipsec/ipsec6.h>
|
#include <netipsec/ipsec6.h>
|
||||||
#endif /* IPSEC */
|
#endif /* IPSEC */
|
||||||
|
|
||||||
|
#include <security/mac/mac_framework.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UDP protocol inplementation.
|
* UDP protocol inplementation.
|
||||||
* Per RFC 768, August, 1980.
|
* Per RFC 768, August, 1980.
|
||||||
@ -133,7 +138,12 @@ udp6_append(struct inpcb *in6p, struct mbuf *n, int off,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* IPSEC */
|
#endif /* IPSEC */
|
||||||
|
#ifdef MAC
|
||||||
|
if (mac_check_inpcb_deliver(in6p, n) != 0) {
|
||||||
|
m_freem(n);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
opts = NULL;
|
opts = NULL;
|
||||||
if (in6p->in6p_flags & IN6P_CONTROLOPTS ||
|
if (in6p->in6p_flags & IN6P_CONTROLOPTS ||
|
||||||
in6p->inp_socket->so_options & SO_TIMESTAMP)
|
in6p->inp_socket->so_options & SO_TIMESTAMP)
|
||||||
@ -184,6 +194,12 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
|
|||||||
|
|
||||||
udpstat.udps_ipackets++;
|
udpstat.udps_ipackets++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destination port of 0 is illegal, based on RFC768.
|
||||||
|
*/
|
||||||
|
if (uh->uh_dport == 0)
|
||||||
|
goto badunlocked;
|
||||||
|
|
||||||
plen = ntohs(ip6->ip6_plen) - off + sizeof(*ip6);
|
plen = ntohs(ip6->ip6_plen) - off + sizeof(*ip6);
|
||||||
ulen = ntohs((u_short)uh->uh_ulen);
|
ulen = ntohs((u_short)uh->uh_ulen);
|
||||||
|
|
||||||
@ -235,6 +251,15 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
|
|||||||
continue;
|
continue;
|
||||||
if (in6p->in6p_lport != uh->uh_dport)
|
if (in6p->in6p_lport != uh->uh_dport)
|
||||||
continue;
|
continue;
|
||||||
|
/*
|
||||||
|
* XXX: Do not check source port of incoming datagram
|
||||||
|
* unless inp_connect() has been called to bind the
|
||||||
|
* fport part of the 4-tuple; the source could be
|
||||||
|
* trying to talk to us with an ephemeral port.
|
||||||
|
*/
|
||||||
|
if (in6p->inp_fport != 0 &&
|
||||||
|
in6p->inp_fport != uh->uh_sport)
|
||||||
|
continue;
|
||||||
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
|
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
|
||||||
if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr,
|
if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr,
|
||||||
&ip6->ip6_dst))
|
&ip6->ip6_dst))
|
||||||
@ -310,6 +335,10 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
|
|||||||
goto badheadlocked;
|
goto badheadlocked;
|
||||||
}
|
}
|
||||||
INP_INFO_RUNLOCK(&udbinfo);
|
INP_INFO_RUNLOCK(&udbinfo);
|
||||||
|
if (udp_blackhole)
|
||||||
|
goto badunlocked;
|
||||||
|
if (badport_bandlim(BANDLIM_ICMP6_UNREACH) < 0)
|
||||||
|
goto badunlocked;
|
||||||
icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
|
icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
|
||||||
return (IPPROTO_DONE);
|
return (IPPROTO_DONE);
|
||||||
}
|
}
|
||||||
@ -318,6 +347,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
|
|||||||
INP_UNLOCK(in6p);
|
INP_UNLOCK(in6p);
|
||||||
INP_INFO_RUNLOCK(&udbinfo);
|
INP_INFO_RUNLOCK(&udbinfo);
|
||||||
return (IPPROTO_DONE);
|
return (IPPROTO_DONE);
|
||||||
|
|
||||||
badheadlocked:
|
badheadlocked:
|
||||||
INP_INFO_RUNLOCK(&udbinfo);
|
INP_INFO_RUNLOCK(&udbinfo);
|
||||||
badunlocked:
|
badunlocked:
|
||||||
@ -735,7 +765,9 @@ udp6_send(struct socket *so, int flags, struct mbuf *m,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MAC
|
||||||
|
mac_create_mbuf_from_inpcb(inp, m);
|
||||||
|
#endif
|
||||||
error = udp6_output(inp, m, addr, control, td);
|
error = udp6_output(inp, m, addr, control, td);
|
||||||
out:
|
out:
|
||||||
INP_UNLOCK(inp);
|
INP_UNLOCK(inp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user