Deleted Added
full compact
ip_mroute.c (215317) ip_mroute.c (215701)
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 215317 2010-11-14 20:38:11Z dim $");
70__FBSDID("$FreeBSD: head/sys/netinet/ip_mroute.c 215701 2010-11-22 19:32:54Z dim $");
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>

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

116
117#ifndef KTR_IPMF
118#define KTR_IPMF KTR_INET
119#endif
120
121#define VIFI_INVALID ((vifi_t) -1)
122#define M_HASCL(m) ((m)->m_flags & M_EXT)
123
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>

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

116
117#ifndef KTR_IPMF
118#define KTR_IPMF KTR_INET
119#endif
120
121#define VIFI_INVALID ((vifi_t) -1)
122#define M_HASCL(m) ((m)->m_flags & M_EXT)
123
124STATIC_VNET_DEFINE(uint32_t, last_tv_sec); /* last time we processed this */
124static VNET_DEFINE(uint32_t, last_tv_sec); /* last time we processed this */
125#define V_last_tv_sec VNET(last_tv_sec)
126
127static MALLOC_DEFINE(M_MRTABLE, "mroutetbl", "multicast forwarding cache");
128
129/*
130 * Locking. We use two locks: one for the virtual interface table and
131 * one for the forwarding table. These locks may be nested in which case
132 * the VIF lock must always be taken first. Note that each lock is used

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

140#define MROUTER_LOCK_ASSERT() mtx_assert(&mrouter_mtx, MA_OWNED)
141#define MROUTER_LOCK_INIT() \
142 mtx_init(&mrouter_mtx, "IPv4 multicast forwarding", NULL, MTX_DEF)
143#define MROUTER_LOCK_DESTROY() mtx_destroy(&mrouter_mtx)
144
145static int ip_mrouter_cnt; /* # of vnets with active mrouters */
146static int ip_mrouter_unloading; /* Allow no more V_ip_mrouter sockets */
147
125#define V_last_tv_sec VNET(last_tv_sec)
126
127static MALLOC_DEFINE(M_MRTABLE, "mroutetbl", "multicast forwarding cache");
128
129/*
130 * Locking. We use two locks: one for the virtual interface table and
131 * one for the forwarding table. These locks may be nested in which case
132 * the VIF lock must always be taken first. Note that each lock is used

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

140#define MROUTER_LOCK_ASSERT() mtx_assert(&mrouter_mtx, MA_OWNED)
141#define MROUTER_LOCK_INIT() \
142 mtx_init(&mrouter_mtx, "IPv4 multicast forwarding", NULL, MTX_DEF)
143#define MROUTER_LOCK_DESTROY() mtx_destroy(&mrouter_mtx)
144
145static int ip_mrouter_cnt; /* # of vnets with active mrouters */
146static int ip_mrouter_unloading; /* Allow no more V_ip_mrouter sockets */
147
148STATIC_VNET_DEFINE(struct mrtstat, mrtstat);
148static VNET_DEFINE(struct mrtstat, mrtstat);
149#define V_mrtstat VNET(mrtstat)
150SYSCTL_VNET_STRUCT(_net_inet_ip, OID_AUTO, mrtstat, CTLFLAG_RW,
151 &VNET_NAME(mrtstat), mrtstat,
152 "IPv4 Multicast Forwarding Statistics (struct mrtstat, "
153 "netinet/ip_mroute.h)");
154
149#define V_mrtstat VNET(mrtstat)
150SYSCTL_VNET_STRUCT(_net_inet_ip, OID_AUTO, mrtstat, CTLFLAG_RW,
151 &VNET_NAME(mrtstat), mrtstat,
152 "IPv4 Multicast Forwarding Statistics (struct mrtstat, "
153 "netinet/ip_mroute.h)");
154
155STATIC_VNET_DEFINE(u_long, mfchash);
155static VNET_DEFINE(u_long, mfchash);
156#define V_mfchash VNET(mfchash)
157#define MFCHASH(a, g) \
158 ((((a).s_addr >> 20) ^ ((a).s_addr >> 10) ^ (a).s_addr ^ \
159 ((g).s_addr >> 20) ^ ((g).s_addr >> 10) ^ (g).s_addr) & V_mfchash)
160#define MFCHASHSIZE 256
161
162static u_long mfchashsize; /* Hash size */
156#define V_mfchash VNET(mfchash)
157#define MFCHASH(a, g) \
158 ((((a).s_addr >> 20) ^ ((a).s_addr >> 10) ^ (a).s_addr ^ \
159 ((g).s_addr >> 20) ^ ((g).s_addr >> 10) ^ (g).s_addr) & V_mfchash)
160#define MFCHASHSIZE 256
161
162static u_long mfchashsize; /* Hash size */
163STATIC_VNET_DEFINE(u_char *, nexpire); /* 0..mfchashsize-1 */
163static VNET_DEFINE(u_char *, nexpire); /* 0..mfchashsize-1 */
164#define V_nexpire VNET(nexpire)
164#define V_nexpire VNET(nexpire)
165STATIC_VNET_DEFINE(LIST_HEAD(mfchashhdr, mfc)*, mfchashtbl);
165static VNET_DEFINE(LIST_HEAD(mfchashhdr, mfc)*, mfchashtbl);
166#define V_mfchashtbl VNET(mfchashtbl)
167
168static struct mtx mfc_mtx;
169#define MFC_LOCK() mtx_lock(&mfc_mtx)
170#define MFC_UNLOCK() mtx_unlock(&mfc_mtx)
171#define MFC_LOCK_ASSERT() mtx_assert(&mfc_mtx, MA_OWNED)
172#define MFC_LOCK_INIT() \
173 mtx_init(&mfc_mtx, "IPv4 multicast forwarding cache", NULL, MTX_DEF)
174#define MFC_LOCK_DESTROY() mtx_destroy(&mfc_mtx)
175
166#define V_mfchashtbl VNET(mfchashtbl)
167
168static struct mtx mfc_mtx;
169#define MFC_LOCK() mtx_lock(&mfc_mtx)
170#define MFC_UNLOCK() mtx_unlock(&mfc_mtx)
171#define MFC_LOCK_ASSERT() mtx_assert(&mfc_mtx, MA_OWNED)
172#define MFC_LOCK_INIT() \
173 mtx_init(&mfc_mtx, "IPv4 multicast forwarding cache", NULL, MTX_DEF)
174#define MFC_LOCK_DESTROY() mtx_destroy(&mfc_mtx)
175
176STATIC_VNET_DEFINE(vifi_t, numvifs);
176static VNET_DEFINE(vifi_t, numvifs);
177#define V_numvifs VNET(numvifs)
177#define V_numvifs VNET(numvifs)
178STATIC_VNET_DEFINE(struct vif, viftable[MAXVIFS]);
178static VNET_DEFINE(struct vif, viftable[MAXVIFS]);
179#define V_viftable VNET(viftable)
180SYSCTL_VNET_OPAQUE(_net_inet_ip, OID_AUTO, viftable, CTLFLAG_RD,
181 &VNET_NAME(viftable), sizeof(V_viftable), "S,vif[MAXVIFS]",
182 "IPv4 Multicast Interfaces (struct vif[MAXVIFS], netinet/ip_mroute.h)");
183
184static struct mtx vif_mtx;
185#define VIF_LOCK() mtx_lock(&vif_mtx)
186#define VIF_UNLOCK() mtx_unlock(&vif_mtx)
187#define VIF_LOCK_ASSERT() mtx_assert(&vif_mtx, MA_OWNED)
188#define VIF_LOCK_INIT() \
189 mtx_init(&vif_mtx, "IPv4 multicast interfaces", NULL, MTX_DEF)
190#define VIF_LOCK_DESTROY() mtx_destroy(&vif_mtx)
191
192static eventhandler_tag if_detach_event_tag = NULL;
193
179#define V_viftable VNET(viftable)
180SYSCTL_VNET_OPAQUE(_net_inet_ip, OID_AUTO, viftable, CTLFLAG_RD,
181 &VNET_NAME(viftable), sizeof(V_viftable), "S,vif[MAXVIFS]",
182 "IPv4 Multicast Interfaces (struct vif[MAXVIFS], netinet/ip_mroute.h)");
183
184static struct mtx vif_mtx;
185#define VIF_LOCK() mtx_lock(&vif_mtx)
186#define VIF_UNLOCK() mtx_unlock(&vif_mtx)
187#define VIF_LOCK_ASSERT() mtx_assert(&vif_mtx, MA_OWNED)
188#define VIF_LOCK_INIT() \
189 mtx_init(&vif_mtx, "IPv4 multicast interfaces", NULL, MTX_DEF)
190#define VIF_LOCK_DESTROY() mtx_destroy(&vif_mtx)
191
192static eventhandler_tag if_detach_event_tag = NULL;
193
194STATIC_VNET_DEFINE(struct callout, expire_upcalls_ch);
194static VNET_DEFINE(struct callout, expire_upcalls_ch);
195#define V_expire_upcalls_ch VNET(expire_upcalls_ch)
196
197#define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */
198#define UPCALL_EXPIRE 6 /* number of timeouts */
199
200/*
201 * Bandwidth meter variables and constants
202 */
203static MALLOC_DEFINE(M_BWMETER, "bwmeter", "multicast upcall bw meters");
204/*
205 * Pending timeouts are stored in a hash table, the key being the
206 * expiration time. Periodically, the entries are analysed and processed.
207 */
208#define BW_METER_BUCKETS 1024
195#define V_expire_upcalls_ch VNET(expire_upcalls_ch)
196
197#define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */
198#define UPCALL_EXPIRE 6 /* number of timeouts */
199
200/*
201 * Bandwidth meter variables and constants
202 */
203static MALLOC_DEFINE(M_BWMETER, "bwmeter", "multicast upcall bw meters");
204/*
205 * Pending timeouts are stored in a hash table, the key being the
206 * expiration time. Periodically, the entries are analysed and processed.
207 */
208#define BW_METER_BUCKETS 1024
209STATIC_VNET_DEFINE(struct bw_meter*, bw_meter_timers[BW_METER_BUCKETS]);
209static VNET_DEFINE(struct bw_meter*, bw_meter_timers[BW_METER_BUCKETS]);
210#define V_bw_meter_timers VNET(bw_meter_timers)
210#define V_bw_meter_timers VNET(bw_meter_timers)
211STATIC_VNET_DEFINE(struct callout, bw_meter_ch);
211static VNET_DEFINE(struct callout, bw_meter_ch);
212#define V_bw_meter_ch VNET(bw_meter_ch)
213#define BW_METER_PERIOD (hz) /* periodical handling of bw meters */
214
215/*
216 * Pending upcalls are stored in a vector which is flushed when
217 * full, or periodically
218 */
212#define V_bw_meter_ch VNET(bw_meter_ch)
213#define BW_METER_PERIOD (hz) /* periodical handling of bw meters */
214
215/*
216 * Pending upcalls are stored in a vector which is flushed when
217 * full, or periodically
218 */
219STATIC_VNET_DEFINE(struct bw_upcall, bw_upcalls[BW_UPCALLS_MAX]);
219static VNET_DEFINE(struct bw_upcall, bw_upcalls[BW_UPCALLS_MAX]);
220#define V_bw_upcalls VNET(bw_upcalls)
220#define V_bw_upcalls VNET(bw_upcalls)
221STATIC_VNET_DEFINE(u_int, bw_upcalls_n); /* # of pending upcalls */
221static VNET_DEFINE(u_int, bw_upcalls_n); /* # of pending upcalls */
222#define V_bw_upcalls_n VNET(bw_upcalls_n)
222#define V_bw_upcalls_n VNET(bw_upcalls_n)
223STATIC_VNET_DEFINE(struct callout, bw_upcalls_ch);
223static VNET_DEFINE(struct callout, bw_upcalls_ch);
224#define V_bw_upcalls_ch VNET(bw_upcalls_ch)
225
226#define BW_UPCALLS_PERIOD (hz) /* periodical flush of bw upcalls */
227
224#define V_bw_upcalls_ch VNET(bw_upcalls_ch)
225
226#define BW_UPCALLS_PERIOD (hz) /* periodical flush of bw upcalls */
227
228STATIC_VNET_DEFINE(struct pimstat, pimstat);
228static VNET_DEFINE(struct pimstat, pimstat);
229#define V_pimstat VNET(pimstat)
230
231SYSCTL_NODE(_net_inet, IPPROTO_PIM, pim, CTLFLAG_RW, 0, "PIM");
232SYSCTL_VNET_STRUCT(_net_inet_pim, PIMCTL_STATS, stats, CTLFLAG_RD,
233 &VNET_NAME(pimstat), pimstat,
234 "PIM Statistics (struct pimstat, netinet/pim_var.h)");
235
236static u_long pim_squelch_wholepkt = 0;

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

291 {
292 PIM_MAKE_VT(PIM_VERSION, PIM_REGISTER), /* PIM vers and message type */
293 0, /* reserved */
294 0, /* checksum */
295 },
296 0 /* flags */
297};
298
229#define V_pimstat VNET(pimstat)
230
231SYSCTL_NODE(_net_inet, IPPROTO_PIM, pim, CTLFLAG_RW, 0, "PIM");
232SYSCTL_VNET_STRUCT(_net_inet_pim, PIMCTL_STATS, stats, CTLFLAG_RD,
233 &VNET_NAME(pimstat), pimstat,
234 "PIM Statistics (struct pimstat, netinet/pim_var.h)");
235
236static u_long pim_squelch_wholepkt = 0;

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

291 {
292 PIM_MAKE_VT(PIM_VERSION, PIM_REGISTER), /* PIM vers and message type */
293 0, /* reserved */
294 0, /* checksum */
295 },
296 0 /* flags */
297};
298
299STATIC_VNET_DEFINE(vifi_t, reg_vif_num) = VIFI_INVALID;
299static VNET_DEFINE(vifi_t, reg_vif_num) = VIFI_INVALID;
300#define V_reg_vif_num VNET(reg_vif_num)
300#define V_reg_vif_num VNET(reg_vif_num)
301STATIC_VNET_DEFINE(struct ifnet, multicast_register_if);
301static VNET_DEFINE(struct ifnet, multicast_register_if);
302#define V_multicast_register_if VNET(multicast_register_if)
303
304/*
305 * Private variables.
306 */
307
308static u_long X_ip_mcast_src(int);
309static int X_ip_mforward(struct ip *, struct ifnet *, struct mbuf *,

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

362 */
363#define MRT_API_VERSION 0x0305
364
365static const int mrt_api_version = MRT_API_VERSION;
366static const uint32_t mrt_api_support = (MRT_MFC_FLAGS_DISABLE_WRONGVIF |
367 MRT_MFC_FLAGS_BORDER_VIF |
368 MRT_MFC_RP |
369 MRT_MFC_BW_UPCALL);
302#define V_multicast_register_if VNET(multicast_register_if)
303
304/*
305 * Private variables.
306 */
307
308static u_long X_ip_mcast_src(int);
309static int X_ip_mforward(struct ip *, struct ifnet *, struct mbuf *,

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

362 */
363#define MRT_API_VERSION 0x0305
364
365static const int mrt_api_version = MRT_API_VERSION;
366static const uint32_t mrt_api_support = (MRT_MFC_FLAGS_DISABLE_WRONGVIF |
367 MRT_MFC_FLAGS_BORDER_VIF |
368 MRT_MFC_RP |
369 MRT_MFC_BW_UPCALL);
370STATIC_VNET_DEFINE(uint32_t, mrt_api_config);
370static VNET_DEFINE(uint32_t, mrt_api_config);
371#define V_mrt_api_config VNET(mrt_api_config)
371#define V_mrt_api_config VNET(mrt_api_config)
372STATIC_VNET_DEFINE(int, pim_assert_enabled);
372static VNET_DEFINE(int, pim_assert_enabled);
373#define V_pim_assert_enabled VNET(pim_assert_enabled)
374static struct timeval pim_assert_interval = { 3, 0 }; /* Rate limit */
375
376/*
377 * Find a route for a given origin IP address and multicast group address.
378 * Statistics must be updated by the caller.
379 */
380static __inline struct mfc *

--- 2568 unchanged lines hidden ---
373#define V_pim_assert_enabled VNET(pim_assert_enabled)
374static struct timeval pim_assert_interval = { 3, 0 }; /* Rate limit */
375
376/*
377 * Find a route for a given origin IP address and multicast group address.
378 * Statistics must be updated by the caller.
379 */
380static __inline struct mfc *

--- 2568 unchanged lines hidden ---