Deleted Added
sdiff udiff text old ( 189303 ) new ( 191672 )
full compact
1/*-
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 47 unchanged lines hidden (view full) ---

56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
61 */
62
63#include <sys/cdefs.h>
64__FBSDID("$FreeBSD: head/sys/netinet6/ip6_output.c 191672 2009-04-29 19:19:13Z bms $");
65
66#include "opt_inet.h"
67#include "opt_inet6.h"
68#include "opt_ipsec.h"
69#include "opt_route.h"
70
71#include <sys/param.h>
72#include <sys/kernel.h>

--- 32 unchanged lines hidden (view full) ---

105#include <netipsec/key.h>
106#include <netinet6/ip6_ipsec.h>
107#endif /* IPSEC */
108
109#include <netinet6/ip6protosw.h>
110#include <netinet6/scope6_var.h>
111#include <netinet6/vinet6.h>
112
113extern int in6_mcast_loop;
114
115struct ip6_exthdrs {
116 struct mbuf *ip6e_ip6;
117 struct mbuf *ip6e_hbh;
118 struct mbuf *ip6e_dest1;
119 struct mbuf *ip6e_rthdr;
120 struct mbuf *ip6e_dest2;
121};
122
123static int ip6_pcbopt __P((int, u_char *, int, struct ip6_pktopts **,
124 struct ucred *, int));
125static int ip6_pcbopts __P((struct ip6_pktopts **, struct mbuf *,
126 struct socket *, struct sockopt *));
127static int ip6_getpcbopt(struct ip6_pktopts *, int, struct sockopt *);
128static int ip6_setpktopt __P((int, u_char *, int, struct ip6_pktopts *,
129 struct ucred *, int, int, int));
130
131static int ip6_copyexthdr(struct mbuf **, caddr_t, int);
132static int ip6_insertfraghdr __P((struct mbuf *, struct mbuf *, int,
133 struct ip6_frag **));
134static int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t);
135static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *);
136static int ip6_getpmtu __P((struct route_in6 *, struct route_in6 *,
137 struct ifnet *, struct in6_addr *, u_long *, int *));
138static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int);

--- 546 unchanged lines hidden (view full) ---

685 }
686 else if ((rt->rt_flags & RTF_GATEWAY))
687 dst = (struct sockaddr_in6 *)rt->rt_gateway;
688 }
689
690 if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
691 m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
692 } else {
693 m->m_flags = (m->m_flags & ~M_BCAST) | M_MCAST;
694 in6_ifstat_inc(ifp, ifs6_out_mcast);
695 /*
696 * Confirm that the outgoing interface supports multicast.
697 */
698 if (!(ifp->if_flags & IFF_MULTICAST)) {
699 V_ip6stat.ip6s_noroute++;
700 in6_ifstat_inc(ifp, ifs6_out_discard);
701 error = ENETUNREACH;
702 goto bad;
703 }
704 if ((im6o == NULL && in6_mcast_loop) ||
705 (im6o && im6o->im6o_multicast_loop)) {
706 /*
707 * Loop back multicast datagram if not expressly
708 * forbidden to do so, even if we have not joined
709 * the address; protocols will filter it later,
710 * thus deferring a hash lookup and lock acquisition
711 * at the expense of an m_copym().
712 */
713 ip6_mloopback(ifp, m, dst);
714 } else {
715 /*
716 * If we are acting as a multicast router, perform
717 * multicast forwarding as if the packet had just
718 * arrived on the interface to which we are about
719 * to send. The multicast forwarding function
720 * recursively calls this function, using the
721 * IPV6_FORWARDING flag to prevent infinite recursion.
722 *
723 * Multicasts that are looped back by ip6_mloopback(),
724 * above, will be forwarded by the ip6_input() routine,
725 * if necessary.
726 */
727 if (V_ip6_mrouter && (flags & IPV6_FORWARDING) == 0) {
728 /*
729 * XXX: ip6_mforward expects that rcvif is NULL
730 * when it is called from the originating path.
731 * However, it is not always the case, since
732 * some versions of MGETHDR() does not
733 * initialize the field.
734 */
735 m->m_pkthdr.rcvif = NULL;

--- 956 unchanged lines hidden (view full) ---

1692 }
1693#undef OPTSET
1694
1695 case IPV6_MULTICAST_IF:
1696 case IPV6_MULTICAST_HOPS:
1697 case IPV6_MULTICAST_LOOP:
1698 case IPV6_JOIN_GROUP:
1699 case IPV6_LEAVE_GROUP:
1700 case IPV6_MSFILTER:
1701 case MCAST_BLOCK_SOURCE:
1702 case MCAST_UNBLOCK_SOURCE:
1703 case MCAST_JOIN_GROUP:
1704 case MCAST_LEAVE_GROUP:
1705 case MCAST_JOIN_SOURCE_GROUP:
1706 case MCAST_LEAVE_SOURCE_GROUP:
1707 error = ip6_setmoptions(in6p, sopt);
1708 break;
1709
1710 case IPV6_PORTRANGE:
1711 error = sooptcopyin(sopt, &optval,
1712 sizeof optval, sizeof optval);
1713 if (error)
1714 break;
1715

--- 215 unchanged lines hidden (view full) ---

1931 case IPV6_PREFER_TEMPADDR:
1932 error = ip6_getpcbopt(in6p->in6p_outputopts,
1933 optname, sopt);
1934 break;
1935
1936 case IPV6_MULTICAST_IF:
1937 case IPV6_MULTICAST_HOPS:
1938 case IPV6_MULTICAST_LOOP:
1939 case IPV6_MSFILTER:
1940 error = ip6_getmoptions(in6p, sopt);
1941 break;
1942
1943#ifdef IPSEC
1944 case IPV6_IPSEC_POLICY:
1945 {
1946 caddr_t req = NULL;
1947 size_t len = 0;
1948 struct mbuf *m = NULL;

--- 404 unchanged lines hidden (view full) ---

2353 return;
2354
2355 ip6_clearpktopts(pktopt, -1);
2356
2357 free(pktopt, M_IP6OPT);
2358}
2359
2360/*
2361 * Set IPv6 outgoing packet options based on advanced API.
2362 */
2363int
2364ip6_setpktopts(struct mbuf *control, struct ip6_pktopts *opt,
2365 struct ip6_pktopts *stickyopt, struct ucred *cred, int uproto)
2366{
2367 struct cmsghdr *cm = 0;
2368

--- 550 unchanged lines hidden ---