Deleted Added
full compact
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 ---