Index: netinet/ip_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_output.c,v
retrieving revision 1.230
diff -u -p -r1.230 ip_output.c
--- netinet/ip_output.c	6 Jun 2014 00:11:19 -0000	1.230
+++ netinet/ip_output.c	11 Oct 2014 15:54:11 -0000
@@ -136,8 +136,6 @@ static struct mbuf *ip_insertoptions(str
 static struct ifnet *ip_multicast_if(struct in_addr *, int *);
 static void ip_mloopback(struct ifnet *, struct mbuf *,
     const struct sockaddr_in *);
-static int ip_setmoptions(struct inpcb *, const struct sockopt *);
-static int ip_getmoptions(struct inpcb *, struct sockopt *);
 
 extern pfil_head_t *inet_pfil_hook;			/* XXX */
 
@@ -1003,7 +1001,7 @@ ip_ctloutput(int op, struct socket *so, 
 		case IP_MULTICAST_LOOP:
 		case IP_ADD_MEMBERSHIP:
 		case IP_DROP_MEMBERSHIP:
-			error = ip_setmoptions(inp, sopt);
+			error = ip_setmoptions(&inp->inp_moptions, sopt);
 			break;
 
 		case IP_PORTRANGE:
@@ -1151,7 +1149,7 @@ ip_ctloutput(int op, struct socket *so, 
 		case IP_MULTICAST_LOOP:
 		case IP_ADD_MEMBERSHIP:
 		case IP_DROP_MEMBERSHIP:
-			error = ip_getmoptions(inp, sopt);
+			error = ip_getmoptions(inp->inp_moptions, sopt);
 			break;
 
 		case IP_PORTRANGE:
@@ -1364,10 +1362,10 @@ ip_getoptval(const struct sockopt *sopt,
 /*
  * Set the IP multicast options in response to user setsockopt().
  */
-static int
-ip_setmoptions(struct inpcb *inp, const struct sockopt *sopt)
+int
+ip_setmoptions(struct ip_moptions **pimo, const struct sockopt *sopt)
 {
-	struct ip_moptions *imo = inp->inp_moptions;
+	struct ip_moptions *imo = *pimo;
 	struct in_addr addr;
 	struct ip_mreq lmreq, *mreq;
 	struct ifnet *ifp;
@@ -1387,7 +1385,7 @@ ip_setmoptions(struct inpcb *inp, const 
 		imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
 		imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
 		imo->imo_num_memberships = 0;
-		inp->inp_moptions = imo;
+		*pimo = imo;
 	}
 
 	switch (sopt->sopt_name) {
@@ -1583,7 +1581,7 @@ ip_setmoptions(struct inpcb *inp, const 
 	    imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&
 	    imo->imo_num_memberships == 0) {
 		kmem_free(imo, sizeof(*imo));
-		inp->inp_moptions = NULL;
+		*pimo = NULL;
 	}
 
 	return error;
@@ -1592,10 +1590,9 @@ ip_setmoptions(struct inpcb *inp, const 
 /*
  * Return the IP multicast options in response to user getsockopt().
  */
-static int
-ip_getmoptions(struct inpcb *inp, struct sockopt *sopt)
+int
+ip_getmoptions(struct ip_moptions *imo, struct sockopt *sopt)
 {
-	struct ip_moptions *imo = inp->inp_moptions;
 	struct in_addr addr;
 	struct in_ifaddr *ia;
 	uint8_t optval;
Index: netinet/ip_var.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_var.h,v
retrieving revision 1.106
diff -u -p -r1.106 ip_var.h
--- netinet/ip_var.h	5 Jun 2014 23:48:16 -0000	1.106
+++ netinet/ip_var.h	11 Oct 2014 15:54:12 -0000
@@ -234,6 +234,9 @@ int	 rip_output(struct mbuf *, ...);
 int	 rip_usrreq(struct socket *,
 	    int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *);
 
+int	ip_setmoptions(struct ip_moptions **, const struct sockopt *sopt);
+int	ip_getmoptions(struct ip_moptions *, struct sockopt *sopt);
+
 /* IP Flow interface. */
 void	ipflow_init(void);
 void	ipflow_poolinit(void);
Index: netinet6/in6_pcb.h
===================================================================
RCS file: /cvsroot/src/sys/netinet6/in6_pcb.h,v
retrieving revision 1.39
diff -u -p -r1.39 in6_pcb.h
--- netinet6/in6_pcb.h	5 Aug 2014 05:24:27 -0000	1.39
+++ netinet6/in6_pcb.h	11 Oct 2014 15:54:13 -0000
@@ -96,7 +96,10 @@ struct	in6pcb {
 	struct	ip6_hdr in6p_ip6;	/* header prototype */
 	struct	mbuf *in6p_options;   /* IP6 options */
 	struct	ip6_pktopts *in6p_outputopts; /* IP6 options for outgoing packets */
-	struct	ip6_moptions *in6p_moptions; /* IP6 multicast options */
+	union {
+		struct ip6_moptions *in6p_moptions; /* IP6 multicast options */
+		struct ip_moptions *in6p_v4moptions;
+	};
 	struct icmp6_filter *in6p_icmp6filt;
 	int	in6p_cksum;		/* IPV6_CHECKSUM setsockopt */
 	bool    in6p_bindportonsend;
Index: netinet6/ip6_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.158
diff -u -p -r1.158 ip6_output.c
--- netinet6/ip6_output.c	16 Aug 2014 17:27:09 -0000	1.158
+++ netinet6/ip6_output.c	11 Oct 2014 15:54:13 -0000
@@ -86,6 +86,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_output.c
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/ip6.h>
+#include <netinet/ip_var.h>
 #include <netinet/icmp6.h>
 #include <netinet/in_offload.h>
 #include <netinet/portalgo.h>
@@ -1264,6 +1265,7 @@ ip6_ctloutput(int op, struct socket *so,
 	int optdatalen, uproto;
 	void *optdata;
 	struct in6pcb *in6p = sotoin6pcb(so);
+	struct ip_moptions **mopts;
 	int error, optval;
 	int level, optname;
 
@@ -1275,9 +1277,32 @@ ip6_ctloutput(int op, struct socket *so,
 	error = optval = 0;
 	uproto = (int)so->so_proto->pr_protocol;
 
-	if (level != IPPROTO_IPV6) {
+	switch (level) {
+	case IPPROTO_IP:
+		switch (optname) {
+		case IP_ADD_MEMBERSHIP:
+		case IP_DROP_MEMBERSHIP:
+		case IP_MULTICAST_IF:
+		case IP_MULTICAST_LOOP:
+		case IP_MULTICAST_TTL:
+			mopts = &in6p->in6p_v4moptions;
+			switch (op) {
+			case PRCO_GETOPT:
+				return ip_getmoptions(*mopts, sopt);
+			case PRCO_SETOPT:
+				return ip_setmoptions(mopts, sopt);
+			default:
+				return EINVAL;
+			}
+		default:
+			return ENOPROTOOPT;
+		}
+	case IPPROTO_IPV6:
+		break;
+	default:
 		return ENOPROTOOPT;
 	}
+
 	switch (op) {
 	case PRCO_SETOPT:
 		switch (optname) {
Index: netinet6/udp6_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/udp6_output.c,v
retrieving revision 1.44
diff -u -p -r1.44 udp6_output.c
--- netinet6/udp6_output.c	6 Jan 2013 00:17:13 -0000	1.44
+++ netinet6/udp6_output.c	11 Oct 2014 15:54:13 -0000
@@ -404,7 +404,7 @@ udp6_output(struct in6pcb * const in6p, 
 
 		UDP_STATINC(UDP_STAT_OPACKETS);
 		error = ip_output(m, NULL, &in6p->in6p_route, flags /* XXX */,
-		    NULL, (struct socket *)in6p->in6p_socket);
+		    in6p->in6p_v4moptions, (struct socket *)in6p->in6p_socket);
 		break;
 #else
 		error = EAFNOSUPPORT;