ip_mroute.c (261024) | ip_mroute.c (269699) |
---|---|
1/*- 2 * Copyright (c) 1989 Stephen Deering 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Stephen Deering of Stanford University. 8 * --- 53 unchanged lines hidden (view full) --- 62 * TODO: Cleanup LSRR removal further. 63 * TODO: Push RSVP stubs into raw_ip.c. 64 * TODO: Use bitstring.h for vif set. 65 * TODO: Fix mrt6_ioctl dangling ref when dynamically loaded. 66 * TODO: Sync ip6_mroute.c with this file. 67 */ 68 69#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1989 Stephen Deering 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Stephen Deering of Stanford University. 8 * --- 53 unchanged lines hidden (view full) --- 62 * TODO: Cleanup LSRR removal further. 63 * TODO: Push RSVP stubs into raw_ip.c. 64 * TODO: Use bitstring.h for vif set. 65 * TODO: Fix mrt6_ioctl dangling ref when dynamically loaded. 66 * TODO: Sync ip6_mroute.c with this file. 67 */ 68 69#include <sys/cdefs.h> |
70__FBSDID("$FreeBSD: head/sys/netinet/ip_mroute.c 261024 2014-01-22 10:57:42Z glebius $"); | 70__FBSDID("$FreeBSD: head/sys/netinet/ip_mroute.c 269699 2014-08-08 01:57:15Z kevlo $"); |
71 72#include "opt_inet.h" 73#include "opt_mrouting.h" 74 75#define _PIM_VT 1 76 77#include <sys/param.h> 78#include <sys/kernel.h> --- 163 unchanged lines hidden (view full) --- 242 243extern struct domain inetdomain; 244static const struct protosw in_pim_protosw = { 245 .pr_type = SOCK_RAW, 246 .pr_domain = &inetdomain, 247 .pr_protocol = IPPROTO_PIM, 248 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 249 .pr_input = pim_input, | 71 72#include "opt_inet.h" 73#include "opt_mrouting.h" 74 75#define _PIM_VT 1 76 77#include <sys/param.h> 78#include <sys/kernel.h> --- 163 unchanged lines hidden (view full) --- 242 243extern struct domain inetdomain; 244static const struct protosw in_pim_protosw = { 245 .pr_type = SOCK_RAW, 246 .pr_domain = &inetdomain, 247 .pr_protocol = IPPROTO_PIM, 248 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 249 .pr_input = pim_input, |
250 .pr_output = (pr_output_t*)rip_output, | 250 .pr_output = (pr_output_t *)rip_output, |
251 .pr_ctloutput = rip_ctloutput, 252 .pr_usrreqs = &rip_usrreqs 253}; 254static const struct encaptab *pim_encap_cookie; 255 256static int pim_encapcheck(const struct mbuf *, int, int, void *); 257 258/* --- 1454 unchanged lines hidden (view full) --- 1713} 1714 1715static void 1716X_ip_rsvp_force_done(struct socket *so __unused) 1717{ 1718 1719} 1720 | 251 .pr_ctloutput = rip_ctloutput, 252 .pr_usrreqs = &rip_usrreqs 253}; 254static const struct encaptab *pim_encap_cookie; 255 256static int pim_encapcheck(const struct mbuf *, int, int, void *); 257 258/* --- 1454 unchanged lines hidden (view full) --- 1713} 1714 1715static void 1716X_ip_rsvp_force_done(struct socket *so __unused) 1717{ 1718 1719} 1720 |
1721static void 1722X_rsvp_input(struct mbuf *m, int off __unused) | 1721static int 1722X_rsvp_input(struct mbuf **mp, int *offp, int proto) |
1723{ | 1723{ |
1724 struct mbuf *m; |
|
1724 | 1725 |
1726 m = *mp; 1727 *mp = NULL; |
|
1725 if (!V_rsvp_on) 1726 m_freem(m); | 1728 if (!V_rsvp_on) 1729 m_freem(m); |
1730 return (IPPROTO_DONE); |
|
1727} 1728 1729/* 1730 * Code for bandwidth monitors 1731 */ 1732 1733/* 1734 * Define common interface for timeval-related methods --- 816 unchanged lines hidden (view full) --- 2551/* 2552 * PIM-SMv2 and PIM-DM messages processing. 2553 * Receives and verifies the PIM control messages, and passes them 2554 * up to the listening socket, using rip_input(). 2555 * The only message with special processing is the PIM_REGISTER message 2556 * (used by PIM-SM): the PIM header is stripped off, and the inner packet 2557 * is passed to if_simloop(). 2558 */ | 1731} 1732 1733/* 1734 * Code for bandwidth monitors 1735 */ 1736 1737/* 1738 * Define common interface for timeval-related methods --- 816 unchanged lines hidden (view full) --- 2555/* 2556 * PIM-SMv2 and PIM-DM messages processing. 2557 * Receives and verifies the PIM control messages, and passes them 2558 * up to the listening socket, using rip_input(). 2559 * The only message with special processing is the PIM_REGISTER message 2560 * (used by PIM-SM): the PIM header is stripped off, and the inner packet 2561 * is passed to if_simloop(). 2562 */ |
2559void 2560pim_input(struct mbuf *m, int iphlen) | 2563int 2564pim_input(struct mbuf **mp, int *offp, int proto) |
2561{ | 2565{ |
2566 struct mbuf *m = *mp; |
|
2562 struct ip *ip = mtod(m, struct ip *); 2563 struct pim *pim; | 2567 struct ip *ip = mtod(m, struct ip *); 2568 struct pim *pim; |
2569 int iphlen = *offp; |
|
2564 int minlen; 2565 int datalen = ntohs(ip->ip_len) - iphlen; 2566 int ip_tos; 2567 | 2570 int minlen; 2571 int datalen = ntohs(ip->ip_len) - iphlen; 2572 int ip_tos; 2573 |
2574 *mp = NULL; 2575 |
|
2568 /* Keep statistics */ 2569 PIMSTAT_INC(pims_rcv_total_msgs); 2570 PIMSTAT_ADD(pims_rcv_total_bytes, datalen); 2571 2572 /* 2573 * Validate lengths 2574 */ 2575 if (datalen < PIM_MINLEN) { 2576 PIMSTAT_INC(pims_rcv_tooshort); 2577 CTR3(KTR_IPMF, "%s: short packet (%d) from %s", 2578 __func__, datalen, inet_ntoa(ip->ip_src)); 2579 m_freem(m); | 2576 /* Keep statistics */ 2577 PIMSTAT_INC(pims_rcv_total_msgs); 2578 PIMSTAT_ADD(pims_rcv_total_bytes, datalen); 2579 2580 /* 2581 * Validate lengths 2582 */ 2583 if (datalen < PIM_MINLEN) { 2584 PIMSTAT_INC(pims_rcv_tooshort); 2585 CTR3(KTR_IPMF, "%s: short packet (%d) from %s", 2586 __func__, datalen, inet_ntoa(ip->ip_src)); 2587 m_freem(m); |
2580 return; | 2588 return (IPPROTO_DONE); |
2581 } 2582 2583 /* 2584 * If the packet is at least as big as a REGISTER, go agead 2585 * and grab the PIM REGISTER header size, to avoid another 2586 * possible m_pullup() later. 2587 * 2588 * PIM_MINLEN == pimhdr + u_int32_t == 4 + 4 = 8 2589 * PIM_REG_MINLEN == pimhdr + reghdr + encap_iphdr == 4 + 4 + 20 = 28 2590 */ 2591 minlen = iphlen + (datalen >= PIM_REG_MINLEN ? PIM_REG_MINLEN : PIM_MINLEN); 2592 /* 2593 * Get the IP and PIM headers in contiguous memory, and 2594 * possibly the PIM REGISTER header. 2595 */ 2596 if (m->m_len < minlen && (m = m_pullup(m, minlen)) == 0) { 2597 CTR1(KTR_IPMF, "%s: m_pullup() failed", __func__); | 2589 } 2590 2591 /* 2592 * If the packet is at least as big as a REGISTER, go agead 2593 * and grab the PIM REGISTER header size, to avoid another 2594 * possible m_pullup() later. 2595 * 2596 * PIM_MINLEN == pimhdr + u_int32_t == 4 + 4 = 8 2597 * PIM_REG_MINLEN == pimhdr + reghdr + encap_iphdr == 4 + 4 + 20 = 28 2598 */ 2599 minlen = iphlen + (datalen >= PIM_REG_MINLEN ? PIM_REG_MINLEN : PIM_MINLEN); 2600 /* 2601 * Get the IP and PIM headers in contiguous memory, and 2602 * possibly the PIM REGISTER header. 2603 */ 2604 if (m->m_len < minlen && (m = m_pullup(m, minlen)) == 0) { 2605 CTR1(KTR_IPMF, "%s: m_pullup() failed", __func__); |
2598 return; | 2606 return (IPPROTO_DONE); |
2599 } 2600 2601 /* m_pullup() may have given us a new mbuf so reset ip. */ 2602 ip = mtod(m, struct ip *); 2603 ip_tos = ip->ip_tos; 2604 2605 /* adjust mbuf to point to the PIM header */ 2606 m->m_data += iphlen; --- 8 unchanged lines hidden (view full) --- 2615 * message, and if error, then over the whole message. 2616 */ 2617 if (PIM_VT_T(pim->pim_vt) == PIM_REGISTER && in_cksum(m, PIM_MINLEN) == 0) { 2618 /* do nothing, checksum okay */ 2619 } else if (in_cksum(m, datalen)) { 2620 PIMSTAT_INC(pims_rcv_badsum); 2621 CTR1(KTR_IPMF, "%s: invalid checksum", __func__); 2622 m_freem(m); | 2607 } 2608 2609 /* m_pullup() may have given us a new mbuf so reset ip. */ 2610 ip = mtod(m, struct ip *); 2611 ip_tos = ip->ip_tos; 2612 2613 /* adjust mbuf to point to the PIM header */ 2614 m->m_data += iphlen; --- 8 unchanged lines hidden (view full) --- 2623 * message, and if error, then over the whole message. 2624 */ 2625 if (PIM_VT_T(pim->pim_vt) == PIM_REGISTER && in_cksum(m, PIM_MINLEN) == 0) { 2626 /* do nothing, checksum okay */ 2627 } else if (in_cksum(m, datalen)) { 2628 PIMSTAT_INC(pims_rcv_badsum); 2629 CTR1(KTR_IPMF, "%s: invalid checksum", __func__); 2630 m_freem(m); |
2623 return; | 2631 return (IPPROTO_DONE); |
2624 } 2625 2626 /* PIM version check */ 2627 if (PIM_VT_V(pim->pim_vt) < PIM_VERSION) { 2628 PIMSTAT_INC(pims_rcv_badversion); 2629 CTR3(KTR_IPMF, "%s: bad version %d expect %d", __func__, 2630 (int)PIM_VT_V(pim->pim_vt), PIM_VERSION); 2631 m_freem(m); | 2632 } 2633 2634 /* PIM version check */ 2635 if (PIM_VT_V(pim->pim_vt) < PIM_VERSION) { 2636 PIMSTAT_INC(pims_rcv_badversion); 2637 CTR3(KTR_IPMF, "%s: bad version %d expect %d", __func__, 2638 (int)PIM_VT_V(pim->pim_vt), PIM_VERSION); 2639 m_freem(m); |
2632 return; | 2640 return (IPPROTO_DONE); |
2633 } 2634 2635 /* restore mbuf back to the outer IP */ 2636 m->m_data -= iphlen; 2637 m->m_len += iphlen; 2638 2639 if (PIM_VT_T(pim->pim_vt) == PIM_REGISTER) { 2640 /* --- 8 unchanged lines hidden (view full) --- 2649 struct ifnet *vifp; 2650 2651 VIF_LOCK(); 2652 if ((V_reg_vif_num >= V_numvifs) || (V_reg_vif_num == VIFI_INVALID)) { 2653 VIF_UNLOCK(); 2654 CTR2(KTR_IPMF, "%s: register vif not set: %d", __func__, 2655 (int)V_reg_vif_num); 2656 m_freem(m); | 2641 } 2642 2643 /* restore mbuf back to the outer IP */ 2644 m->m_data -= iphlen; 2645 m->m_len += iphlen; 2646 2647 if (PIM_VT_T(pim->pim_vt) == PIM_REGISTER) { 2648 /* --- 8 unchanged lines hidden (view full) --- 2657 struct ifnet *vifp; 2658 2659 VIF_LOCK(); 2660 if ((V_reg_vif_num >= V_numvifs) || (V_reg_vif_num == VIFI_INVALID)) { 2661 VIF_UNLOCK(); 2662 CTR2(KTR_IPMF, "%s: register vif not set: %d", __func__, 2663 (int)V_reg_vif_num); 2664 m_freem(m); |
2657 return; | 2665 return (IPPROTO_DONE); |
2658 } 2659 /* XXX need refcnt? */ 2660 vifp = V_viftable[V_reg_vif_num].v_ifp; 2661 VIF_UNLOCK(); 2662 2663 /* 2664 * Validate length 2665 */ 2666 if (datalen < PIM_REG_MINLEN) { 2667 PIMSTAT_INC(pims_rcv_tooshort); 2668 PIMSTAT_INC(pims_rcv_badregisters); 2669 CTR1(KTR_IPMF, "%s: register packet size too small", __func__); 2670 m_freem(m); | 2666 } 2667 /* XXX need refcnt? */ 2668 vifp = V_viftable[V_reg_vif_num].v_ifp; 2669 VIF_UNLOCK(); 2670 2671 /* 2672 * Validate length 2673 */ 2674 if (datalen < PIM_REG_MINLEN) { 2675 PIMSTAT_INC(pims_rcv_tooshort); 2676 PIMSTAT_INC(pims_rcv_badregisters); 2677 CTR1(KTR_IPMF, "%s: register packet size too small", __func__); 2678 m_freem(m); |
2671 return; | 2679 return (IPPROTO_DONE); |
2672 } 2673 2674 reghdr = (u_int32_t *)(pim + 1); 2675 encap_ip = (struct ip *)(reghdr + 1); 2676 2677 CTR3(KTR_IPMF, "%s: register: encap ip src %s len %d", 2678 __func__, inet_ntoa(encap_ip->ip_src), ntohs(encap_ip->ip_len)); 2679 2680 /* verify the version number of the inner packet */ 2681 if (encap_ip->ip_v != IPVERSION) { 2682 PIMSTAT_INC(pims_rcv_badregisters); 2683 CTR1(KTR_IPMF, "%s: bad encap ip version", __func__); 2684 m_freem(m); | 2680 } 2681 2682 reghdr = (u_int32_t *)(pim + 1); 2683 encap_ip = (struct ip *)(reghdr + 1); 2684 2685 CTR3(KTR_IPMF, "%s: register: encap ip src %s len %d", 2686 __func__, inet_ntoa(encap_ip->ip_src), ntohs(encap_ip->ip_len)); 2687 2688 /* verify the version number of the inner packet */ 2689 if (encap_ip->ip_v != IPVERSION) { 2690 PIMSTAT_INC(pims_rcv_badregisters); 2691 CTR1(KTR_IPMF, "%s: bad encap ip version", __func__); 2692 m_freem(m); |
2685 return; | 2693 return (IPPROTO_DONE); |
2686 } 2687 2688 /* verify the inner packet is destined to a mcast group */ 2689 if (!IN_MULTICAST(ntohl(encap_ip->ip_dst.s_addr))) { 2690 PIMSTAT_INC(pims_rcv_badregisters); 2691 CTR2(KTR_IPMF, "%s: bad encap ip dest %s", __func__, 2692 inet_ntoa(encap_ip->ip_dst)); 2693 m_freem(m); | 2694 } 2695 2696 /* verify the inner packet is destined to a mcast group */ 2697 if (!IN_MULTICAST(ntohl(encap_ip->ip_dst.s_addr))) { 2698 PIMSTAT_INC(pims_rcv_badregisters); 2699 CTR2(KTR_IPMF, "%s: bad encap ip dest %s", __func__, 2700 inet_ntoa(encap_ip->ip_dst)); 2701 m_freem(m); |
2694 return; | 2702 return (IPPROTO_DONE); |
2695 } 2696 2697 /* If a NULL_REGISTER, pass it to the daemon */ 2698 if ((ntohl(*reghdr) & PIM_NULL_REGISTER)) 2699 goto pim_input_to_daemon; 2700 2701 /* 2702 * Copy the TOS from the outer IP header to the inner IP header. --- 22 unchanged lines hidden (view full) --- 2725 * to pass to the daemon later, so it can take the appropriate 2726 * actions (e.g., send back PIM_REGISTER_STOP). 2727 * XXX: here m->m_data points to the outer IP header. 2728 */ 2729 mcp = m_copy(m, 0, iphlen + PIM_REG_MINLEN); 2730 if (mcp == NULL) { 2731 CTR1(KTR_IPMF, "%s: m_copy() failed", __func__); 2732 m_freem(m); | 2703 } 2704 2705 /* If a NULL_REGISTER, pass it to the daemon */ 2706 if ((ntohl(*reghdr) & PIM_NULL_REGISTER)) 2707 goto pim_input_to_daemon; 2708 2709 /* 2710 * Copy the TOS from the outer IP header to the inner IP header. --- 22 unchanged lines hidden (view full) --- 2733 * to pass to the daemon later, so it can take the appropriate 2734 * actions (e.g., send back PIM_REGISTER_STOP). 2735 * XXX: here m->m_data points to the outer IP header. 2736 */ 2737 mcp = m_copy(m, 0, iphlen + PIM_REG_MINLEN); 2738 if (mcp == NULL) { 2739 CTR1(KTR_IPMF, "%s: m_copy() failed", __func__); 2740 m_freem(m); |
2733 return; | 2741 return (IPPROTO_DONE); |
2734 } 2735 2736 /* Keep statistics */ 2737 /* XXX: registers_bytes include only the encap. mcast pkt */ 2738 PIMSTAT_INC(pims_rcv_registers_msgs); 2739 PIMSTAT_ADD(pims_rcv_registers_bytes, ntohs(encap_ip->ip_len)); 2740 2741 /* --- 19 unchanged lines hidden (view full) --- 2761 /* 2762 * Pass the PIM message up to the daemon; if it is a Register message, 2763 * pass the 'head' only up to the daemon. This includes the 2764 * outer IP header, PIM header, PIM-Register header and the 2765 * inner IP header. 2766 * XXX: the outer IP header pkt size of a Register is not adjust to 2767 * reflect the fact that the inner multicast data is truncated. 2768 */ | 2742 } 2743 2744 /* Keep statistics */ 2745 /* XXX: registers_bytes include only the encap. mcast pkt */ 2746 PIMSTAT_INC(pims_rcv_registers_msgs); 2747 PIMSTAT_ADD(pims_rcv_registers_bytes, ntohs(encap_ip->ip_len)); 2748 2749 /* --- 19 unchanged lines hidden (view full) --- 2769 /* 2770 * Pass the PIM message up to the daemon; if it is a Register message, 2771 * pass the 'head' only up to the daemon. This includes the 2772 * outer IP header, PIM header, PIM-Register header and the 2773 * inner IP header. 2774 * XXX: the outer IP header pkt size of a Register is not adjust to 2775 * reflect the fact that the inner multicast data is truncated. 2776 */ |
2769 rip_input(m, iphlen); | 2777 *mp = m; 2778 rip_input(mp, offp, proto); |
2770 | 2779 |
2771 return; | 2780 return (IPPROTO_DONE); |
2772} 2773 2774static int 2775sysctl_mfctable(SYSCTL_HANDLER_ARGS) 2776{ 2777 struct mfc *rt; 2778 int error, i; 2779 --- 161 unchanged lines hidden --- | 2781} 2782 2783static int 2784sysctl_mfctable(SYSCTL_HANDLER_ARGS) 2785{ 2786 struct mfc *rt; 2787 int error, i; 2788 --- 161 unchanged lines hidden --- |