Deleted Added
full compact
ip6_mroute.c (190012) ip6_mroute.c (191672)
1/*-
2 * Copyright (C) 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

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

74 * Modified by Van Jacobson, LBL, January 1993
75 * Modified by Ajit Thyagarajan, PARC, August 1993
76 * Modified by Bill Fenner, PARC, April 1994
77 *
78 * MROUTING Revision: 3.5.1.2 + PIM-SMv2 (pimd) Support
79 */
80
81#include <sys/cdefs.h>
1/*-
2 * Copyright (C) 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

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

74 * Modified by Van Jacobson, LBL, January 1993
75 * Modified by Ajit Thyagarajan, PARC, August 1993
76 * Modified by Bill Fenner, PARC, April 1994
77 *
78 * MROUTING Revision: 3.5.1.2 + PIM-SMv2 (pimd) Support
79 */
80
81#include <sys/cdefs.h>
82__FBSDID("$FreeBSD: head/sys/netinet6/ip6_mroute.c 190012 2009-03-19 01:43:03Z bms $");
82__FBSDID("$FreeBSD: head/sys/netinet6/ip6_mroute.c 191672 2009-04-29 19:19:13Z bms $");
83
84#include "opt_inet.h"
85#include "opt_inet6.h"
86#include "opt_route.h"
87
88#include <sys/param.h>
89#include <sys/callout.h>
90#include <sys/errno.h>
91#include <sys/kernel.h>
92#include <sys/lock.h>
93#include <sys/malloc.h>
94#include <sys/mbuf.h>
95#include <sys/module.h>
83
84#include "opt_inet.h"
85#include "opt_inet6.h"
86#include "opt_route.h"
87
88#include <sys/param.h>
89#include <sys/callout.h>
90#include <sys/errno.h>
91#include <sys/kernel.h>
92#include <sys/lock.h>
93#include <sys/malloc.h>
94#include <sys/mbuf.h>
95#include <sys/module.h>
96#include <sys/domain.h>
96#include <sys/protosw.h>
97#include <sys/signalvar.h>
98#include <sys/socket.h>
99#include <sys/socketvar.h>
100#include <sys/sockio.h>
101#include <sys/sx.h>
102#include <sys/sysctl.h>
103#include <sys/syslog.h>

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

135static int ip6_mdq(struct mbuf *, struct ifnet *, struct mf6c *);
136static void phyint_send(struct ip6_hdr *, struct mif6 *, struct mbuf *);
137static void pim6_init(void);
138static int register_send(struct ip6_hdr *, struct mif6 *, struct mbuf *);
139static int set_pim6(int *);
140static int socket_send(struct socket *, struct mbuf *,
141 struct sockaddr_in6 *);
142
97#include <sys/protosw.h>
98#include <sys/signalvar.h>
99#include <sys/socket.h>
100#include <sys/socketvar.h>
101#include <sys/sockio.h>
102#include <sys/sx.h>
103#include <sys/sysctl.h>
104#include <sys/syslog.h>

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

136static int ip6_mdq(struct mbuf *, struct ifnet *, struct mf6c *);
137static void phyint_send(struct ip6_hdr *, struct mif6 *, struct mbuf *);
138static void pim6_init(void);
139static int register_send(struct ip6_hdr *, struct mif6 *, struct mbuf *);
140static int set_pim6(int *);
141static int socket_send(struct socket *, struct mbuf *,
142 struct sockaddr_in6 *);
143
144extern int in6_mcast_loop;
143extern struct domain inet6domain;
144
145static const struct encaptab *pim6_encap_cookie;
146static const struct ip6protosw in6_pim_protosw = {
147 .pr_type = SOCK_RAW,
148 .pr_domain = &inet6domain,
149 .pr_protocol = IPPROTO_PIM,
150 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR,

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

362X_ip6_mrouter_set(struct socket *so, struct sockopt *sopt)
363{
364 int error = 0;
365 int optval;
366 struct mif6ctl mifc;
367 struct mf6cctl mfcc;
368 mifi_t mifi;
369
145extern struct domain inet6domain;
146
147static const struct encaptab *pim6_encap_cookie;
148static const struct ip6protosw in6_pim_protosw = {
149 .pr_type = SOCK_RAW,
150 .pr_domain = &inet6domain,
151 .pr_protocol = IPPROTO_PIM,
152 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR,

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

364X_ip6_mrouter_set(struct socket *so, struct sockopt *sopt)
365{
366 int error = 0;
367 int optval;
368 struct mif6ctl mifc;
369 struct mf6cctl mfcc;
370 mifi_t mifi;
371
370 if (so != ip6_mrouter && sopt->sopt_name != MRT6_INIT)
372 if (so != V_ip6_mrouter && sopt->sopt_name != MRT6_INIT)
371 return (EACCES);
372
373 switch (sopt->sopt_name) {
374 case MRT6_INIT:
375#ifdef MRT6_OINIT
376 case MRT6_OINIT:
377#endif
378 error = sooptcopyin(sopt, &optval, sizeof(optval),

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

427 * Handle MRT getsockopt commands
428 */
429int
430X_ip6_mrouter_get(struct socket *so, struct sockopt *sopt)
431{
432 INIT_VNET_INET6(curvnet);
433 int error = 0;
434
373 return (EACCES);
374
375 switch (sopt->sopt_name) {
376 case MRT6_INIT:
377#ifdef MRT6_OINIT
378 case MRT6_OINIT:
379#endif
380 error = sooptcopyin(sopt, &optval, sizeof(optval),

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

429 * Handle MRT getsockopt commands
430 */
431int
432X_ip6_mrouter_get(struct socket *so, struct sockopt *sopt)
433{
434 INIT_VNET_INET6(curvnet);
435 int error = 0;
436
435 if (so != ip6_mrouter)
437 if (so != V_ip6_mrouter)
436 return (EACCES);
437
438 switch (sopt->sopt_name) {
439 case MRT6_PIM:
440 error = sooptcopyout(sopt, &V_pim6, sizeof(V_pim6));
441 break;
442 }
443 return (error);

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

555 so->so_proto->pr_protocol != IPPROTO_ICMPV6)
556 return (EOPNOTSUPP);
557
558 if (v != 1)
559 return (ENOPROTOOPT);
560
561 MROUTER6_LOCK();
562
438 return (EACCES);
439
440 switch (sopt->sopt_name) {
441 case MRT6_PIM:
442 error = sooptcopyout(sopt, &V_pim6, sizeof(V_pim6));
443 break;
444 }
445 return (error);

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

557 so->so_proto->pr_protocol != IPPROTO_ICMPV6)
558 return (EOPNOTSUPP);
559
560 if (v != 1)
561 return (ENOPROTOOPT);
562
563 MROUTER6_LOCK();
564
563 if (ip6_mrouter != NULL) {
565 if (V_ip6_mrouter != NULL) {
564 MROUTER6_UNLOCK();
565 return (EADDRINUSE);
566 }
567
566 MROUTER6_UNLOCK();
567 return (EADDRINUSE);
568 }
569
568 ip6_mrouter = so;
570 V_ip6_mrouter = so;
569 V_ip6_mrouter_ver = cmd;
570
571 bzero((caddr_t)mf6ctable, sizeof(mf6ctable));
572 bzero((caddr_t)n6expire, sizeof(n6expire));
573
574 V_pim6 = 0;/* used for stubbing out/in pim stuff */
575
576 callout_init(&expire_upcalls_ch, 0);

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

596 INIT_VNET_INET6(curvnet);
597 mifi_t mifi;
598 int i;
599 struct mf6c *rt;
600 struct rtdetq *rte;
601
602 MROUTER6_LOCK();
603
571 V_ip6_mrouter_ver = cmd;
572
573 bzero((caddr_t)mf6ctable, sizeof(mf6ctable));
574 bzero((caddr_t)n6expire, sizeof(n6expire));
575
576 V_pim6 = 0;/* used for stubbing out/in pim stuff */
577
578 callout_init(&expire_upcalls_ch, 0);

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

598 INIT_VNET_INET6(curvnet);
599 mifi_t mifi;
600 int i;
601 struct mf6c *rt;
602 struct rtdetq *rte;
603
604 MROUTER6_LOCK();
605
604 if (ip6_mrouter == NULL) {
606 if (V_ip6_mrouter == NULL) {
605 MROUTER6_UNLOCK();
606 return (EINVAL);
607 }
608
609 /*
610 * For each phyint in use, disable promiscuous reception of all IPv6
611 * multicasts.
612 */

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

652 */
653 if (reg_mif_num != (mifi_t)-1 && multicast_register_if6 != NULL) {
654 if_detach(multicast_register_if6);
655 if_free(multicast_register_if6);
656 reg_mif_num = (mifi_t)-1;
657 multicast_register_if6 = NULL;
658 }
659
607 MROUTER6_UNLOCK();
608 return (EINVAL);
609 }
610
611 /*
612 * For each phyint in use, disable promiscuous reception of all IPv6
613 * multicasts.
614 */

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

654 */
655 if (reg_mif_num != (mifi_t)-1 && multicast_register_if6 != NULL) {
656 if_detach(multicast_register_if6);
657 if_free(multicast_register_if6);
658 reg_mif_num = (mifi_t)-1;
659 multicast_register_if6 = NULL;
660 }
661
660 ip6_mrouter = NULL;
662 V_ip6_mrouter = NULL;
661 V_ip6_mrouter_ver = 0;
662
663 MROUTER6_UNLOCK();
664
665#ifdef MRT6DEBUG
666 if (V_mrt6debug)
667 log(LOG_DEBUG, "ip6_mrouter_done\n");
668#endif

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

1288 oim->im6_mif = mifi;
1289 break;
1290#endif
1291 case MRT6_INIT:
1292 im->im6_mif = mifi;
1293 break;
1294 }
1295
663 V_ip6_mrouter_ver = 0;
664
665 MROUTER6_UNLOCK();
666
667#ifdef MRT6DEBUG
668 if (V_mrt6debug)
669 log(LOG_DEBUG, "ip6_mrouter_done\n");
670#endif

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

1290 oim->im6_mif = mifi;
1291 break;
1292#endif
1293 case MRT6_INIT:
1294 im->im6_mif = mifi;
1295 break;
1296 }
1297
1296 if (socket_send(ip6_mrouter, mm, &sin6) < 0) {
1298 if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) {
1297 log(LOG_WARNING, "ip6_mforward: ip6_mrouter "
1298 "socket queue full\n");
1299 mrt6stat.mrt6s_upq_sockfull++;
1300 free(rte, M_MRTABLE6);
1301 m_freem(mb0);
1302 free(rt, M_MRTABLE6);
1303 MFC6_UNLOCK();
1304 return (ENOBUFS);

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

1526 case MRT6_INIT:
1527 im->im6_mif = iif;
1528 sin6.sin6_addr = im->im6_src;
1529 break;
1530 }
1531
1532 mrt6stat.mrt6s_upcalls++;
1533
1299 log(LOG_WARNING, "ip6_mforward: ip6_mrouter "
1300 "socket queue full\n");
1301 mrt6stat.mrt6s_upq_sockfull++;
1302 free(rte, M_MRTABLE6);
1303 m_freem(mb0);
1304 free(rt, M_MRTABLE6);
1305 MFC6_UNLOCK();
1306 return (ENOBUFS);

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

1528 case MRT6_INIT:
1529 im->im6_mif = iif;
1530 sin6.sin6_addr = im->im6_src;
1531 break;
1532 }
1533
1534 mrt6stat.mrt6s_upcalls++;
1535
1534 if (socket_send(ip6_mrouter, mm, &sin6) < 0) {
1536 if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) {
1535#ifdef MRT6DEBUG
1536 if (V_mrt6debug)
1537 log(LOG_WARNING, "mdq, ip6_mrouter socket queue full\n");
1538#endif
1539 ++mrt6stat.mrt6s_upq_sockfull;
1540 return (ENOBUFS);
1541 } /* if socket Q full */
1542 } /* if PIM */

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

1598
1599static void
1600phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
1601{
1602 INIT_VNET_INET6(curvnet);
1603 struct mbuf *mb_copy;
1604 struct ifnet *ifp = mifp->m6_ifp;
1605 int error = 0;
1537#ifdef MRT6DEBUG
1538 if (V_mrt6debug)
1539 log(LOG_WARNING, "mdq, ip6_mrouter socket queue full\n");
1540#endif
1541 ++mrt6stat.mrt6s_upq_sockfull;
1542 return (ENOBUFS);
1543 } /* if socket Q full */
1544 } /* if PIM */

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

1600
1601static void
1602phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
1603{
1604 INIT_VNET_INET6(curvnet);
1605 struct mbuf *mb_copy;
1606 struct ifnet *ifp = mifp->m6_ifp;
1607 int error = 0;
1606 struct in6_multi *in6m;
1607 struct sockaddr_in6 *dst6;
1608 u_long linkmtu;
1609
1608 struct sockaddr_in6 *dst6;
1609 u_long linkmtu;
1610
1611 dst6 = &mifp->m6_route.ro_dst;
1612
1610 /*
1611 * Make a new reference to the packet; make sure that
1612 * the IPv6 header is actually copied, not just referenced,
1613 * so that ip6_output() only scribbles on the copy.
1614 */
1615 mb_copy = m_copy(m, 0, M_COPYALL);
1616 if (mb_copy &&
1617 (M_HASCL(mb_copy) || mb_copy->m_len < sizeof(struct ip6_hdr)))

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

1643 if (V_mrt6debug & DEBUG_XMIT)
1644 log(LOG_DEBUG, "phyint_send on mif %d err %d\n",
1645 mifp - mif6table, error);
1646#endif
1647 return;
1648 }
1649
1650 /*
1613 /*
1614 * Make a new reference to the packet; make sure that
1615 * the IPv6 header is actually copied, not just referenced,
1616 * so that ip6_output() only scribbles on the copy.
1617 */
1618 mb_copy = m_copy(m, 0, M_COPYALL);
1619 if (mb_copy &&
1620 (M_HASCL(mb_copy) || mb_copy->m_len < sizeof(struct ip6_hdr)))

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

1646 if (V_mrt6debug & DEBUG_XMIT)
1647 log(LOG_DEBUG, "phyint_send on mif %d err %d\n",
1648 mifp - mif6table, error);
1649#endif
1650 return;
1651 }
1652
1653 /*
1651 * If we belong to the destination multicast group
1652 * on the outgoing interface, loop back a copy.
1654 * If configured to loop back multicasts by default,
1655 * loop back a copy now.
1653 */
1656 */
1654 dst6 = &mifp->m6_route.ro_dst;
1655 IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m);
1656 if (in6m != NULL) {
1657 if (in6_mcast_loop) {
1657 dst6->sin6_len = sizeof(struct sockaddr_in6);
1658 dst6->sin6_family = AF_INET6;
1659 dst6->sin6_addr = ip6->ip6_dst;
1660 ip6_mloopback(ifp, m, &mifp->m6_route.ro_dst);
1661 }
1658 dst6->sin6_len = sizeof(struct sockaddr_in6);
1659 dst6->sin6_family = AF_INET6;
1660 dst6->sin6_addr = ip6->ip6_dst;
1661 ip6_mloopback(ifp, m, &mifp->m6_route.ro_dst);
1662 }
1663
1662 /*
1663 * Put the packet into the sending queue of the outgoing interface
1664 * if it would fit in the MTU of the interface.
1665 */
1666 linkmtu = IN6_LINKMTU(ifp);
1667 if (mb_copy->m_pkthdr.len <= linkmtu || linkmtu < IPV6_MMTU) {
1668 dst6->sin6_len = sizeof(struct sockaddr_in6);
1669 dst6->sin6_family = AF_INET6;

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

1754 im6->im6_msgtype = MRT6MSG_WHOLEPKT;
1755 im6->im6_mbz = 0;
1756
1757 im6->im6_mif = mif - mif6table;
1758
1759 /* iif info is not given for reg. encap.n */
1760 mrt6stat.mrt6s_upcalls++;
1761
1664 /*
1665 * Put the packet into the sending queue of the outgoing interface
1666 * if it would fit in the MTU of the interface.
1667 */
1668 linkmtu = IN6_LINKMTU(ifp);
1669 if (mb_copy->m_pkthdr.len <= linkmtu || linkmtu < IPV6_MMTU) {
1670 dst6->sin6_len = sizeof(struct sockaddr_in6);
1671 dst6->sin6_family = AF_INET6;

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

1756 im6->im6_msgtype = MRT6MSG_WHOLEPKT;
1757 im6->im6_mbz = 0;
1758
1759 im6->im6_mif = mif - mif6table;
1760
1761 /* iif info is not given for reg. encap.n */
1762 mrt6stat.mrt6s_upcalls++;
1763
1762 if (socket_send(ip6_mrouter, mm, &sin6) < 0) {
1764 if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) {
1763#ifdef MRT6DEBUG
1764 if (V_mrt6debug)
1765 log(LOG_WARNING,
1766 "register_send: ip6_mrouter socket queue full\n");
1767#endif
1768 ++mrt6stat.mrt6s_upq_sockfull;
1769 return (ENOBUFS);
1770 }

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

2051 ip6_mforward = X_ip6_mforward;
2052 ip6_mrouter_done = X_ip6_mrouter_done;
2053 ip6_mrouter_get = X_ip6_mrouter_get;
2054 ip6_mrouter_set = X_ip6_mrouter_set;
2055 mrt6_ioctl = X_mrt6_ioctl;
2056 break;
2057
2058 case MOD_UNLOAD:
1765#ifdef MRT6DEBUG
1766 if (V_mrt6debug)
1767 log(LOG_WARNING,
1768 "register_send: ip6_mrouter socket queue full\n");
1769#endif
1770 ++mrt6stat.mrt6s_upq_sockfull;
1771 return (ENOBUFS);
1772 }

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

2053 ip6_mforward = X_ip6_mforward;
2054 ip6_mrouter_done = X_ip6_mrouter_done;
2055 ip6_mrouter_get = X_ip6_mrouter_get;
2056 ip6_mrouter_set = X_ip6_mrouter_set;
2057 mrt6_ioctl = X_mrt6_ioctl;
2058 break;
2059
2060 case MOD_UNLOAD:
2059 if (ip6_mrouter != NULL)
2061 if (V_ip6_mrouter != NULL)
2060 return EINVAL;
2061
2062 if (pim6_encap_cookie) {
2063 encap_detach(pim6_encap_cookie);
2064 pim6_encap_cookie = NULL;
2065 }
2066 X_ip6_mrouter_done();
2067 ip6_mforward = NULL;

--- 24 unchanged lines hidden ---
2062 return EINVAL;
2063
2064 if (pim6_encap_cookie) {
2065 encap_detach(pim6_encap_cookie);
2066 pim6_encap_cookie = NULL;
2067 }
2068 X_ip6_mrouter_done();
2069 ip6_mforward = NULL;

--- 24 unchanged lines hidden ---