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 --- |