Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_mroute.c
Show First 20 Lines • Show All 1,118 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
static int | static int | ||||
add_mfc(struct mfcctl2 *mfccp) | add_mfc(struct mfcctl2 *mfccp) | ||||
{ | { | ||||
struct mfc *rt; | struct mfc *rt; | ||||
struct rtdetq *rte; | struct rtdetq *rte; | ||||
u_long hash = 0; | u_long hash = 0; | ||||
u_short nstl; | u_short nstl; | ||||
struct epoch_tracker et; | |||||
MRW_WLOCK(); | MRW_WLOCK(); | ||||
rt = mfc_find(&mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp); | rt = mfc_find(&mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp); | ||||
/* If an entry already exists, just update the fields */ | /* If an entry already exists, just update the fields */ | ||||
if (rt) { | if (rt) { | ||||
CTR4(KTR_IPMF, "%s: update mfc orig 0x%08x group %lx parent %x", | CTR4(KTR_IPMF, "%s: update mfc orig 0x%08x group %lx parent %x", | ||||
__func__, ntohl(mfccp->mfcc_origin.s_addr), | __func__, ntohl(mfccp->mfcc_origin.s_addr), | ||||
(u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr), | (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr), | ||||
mfccp->mfcc_parent); | mfccp->mfcc_parent); | ||||
update_mfc_params(rt, mfccp); | update_mfc_params(rt, mfccp); | ||||
MRW_WUNLOCK(); | MRW_WUNLOCK(); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Find the entry for which the upcall was made and update | * Find the entry for which the upcall was made and update | ||||
*/ | */ | ||||
nstl = 0; | nstl = 0; | ||||
hash = MFCHASH(mfccp->mfcc_origin, mfccp->mfcc_mcastgrp); | hash = MFCHASH(mfccp->mfcc_origin, mfccp->mfcc_mcastgrp); | ||||
NET_EPOCH_ENTER(et); | |||||
LIST_FOREACH(rt, &V_mfchashtbl[hash], mfc_hash) { | LIST_FOREACH(rt, &V_mfchashtbl[hash], mfc_hash) { | ||||
if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && | if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && | ||||
in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp) && | in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp) && | ||||
!buf_ring_empty(rt->mfc_stall_ring)) { | !buf_ring_empty(rt->mfc_stall_ring)) { | ||||
CTR5(KTR_IPMF, | CTR5(KTR_IPMF, | ||||
"%s: add mfc orig 0x%08x group %lx parent %x qh %p", | "%s: add mfc orig 0x%08x group %lx parent %x qh %p", | ||||
__func__, ntohl(mfccp->mfcc_origin.s_addr), | __func__, ntohl(mfccp->mfcc_origin.s_addr), | ||||
(u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr), | (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr), | ||||
Show All 11 Lines | while (!buf_ring_empty(rt->mfc_stall_ring)) { | ||||
rte = buf_ring_dequeue_mc(rt->mfc_stall_ring); | rte = buf_ring_dequeue_mc(rt->mfc_stall_ring); | ||||
if (rte->ifp != NULL) | if (rte->ifp != NULL) | ||||
ip_mdq(rte->m, rte->ifp, rt, -1); | ip_mdq(rte->m, rte->ifp, rt, -1); | ||||
m_freem(rte->m); | m_freem(rte->m); | ||||
free(rte, M_MRTABLE); | free(rte, M_MRTABLE); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
NET_EPOCH_EXIT(et); | |||||
/* | /* | ||||
* It is possible that an entry is being inserted without an upcall | * It is possible that an entry is being inserted without an upcall | ||||
*/ | */ | ||||
if (nstl == 0) { | if (nstl == 0) { | ||||
CTR1(KTR_IPMF, "%s: adding mfc w/o upcall", __func__); | CTR1(KTR_IPMF, "%s: adding mfc w/o upcall", __func__); | ||||
LIST_FOREACH(rt, &V_mfchashtbl[hash], mfc_hash) { | LIST_FOREACH(rt, &V_mfchashtbl[hash], mfc_hash) { | ||||
if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && | if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && | ||||
▲ Show 20 Lines • Show All 361 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
ip_mdq(struct mbuf *m, struct ifnet *ifp, struct mfc *rt, vifi_t xmt_vif) | ip_mdq(struct mbuf *m, struct ifnet *ifp, struct mfc *rt, vifi_t xmt_vif) | ||||
{ | { | ||||
struct ip *ip = mtod(m, struct ip *); | struct ip *ip = mtod(m, struct ip *); | ||||
vifi_t vifi; | vifi_t vifi; | ||||
int plen = ntohs(ip->ip_len); | int plen = ntohs(ip->ip_len); | ||||
MRW_LOCK_ASSERT(); | MRW_LOCK_ASSERT(); | ||||
NET_EPOCH_ASSERT(); | |||||
/* | /* | ||||
* If xmt_vif is not -1, send on only the requested vif. | * If xmt_vif is not -1, send on only the requested vif. | ||||
* | * | ||||
* (since vifi_t is u_short, -1 becomes MAXUSHORT, which > numvifs.) | * (since vifi_t is u_short, -1 becomes MAXUSHORT, which > numvifs.) | ||||
*/ | */ | ||||
if (xmt_vif < V_numvifs) { | if (xmt_vif < V_numvifs) { | ||||
if (V_viftable[xmt_vif].v_flags & VIFF_REGISTER) | if (V_viftable[xmt_vif].v_flags & VIFF_REGISTER) | ||||
▲ Show 20 Lines • Show All 188 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
send_packet(struct vif *vifp, struct mbuf *m) | send_packet(struct vif *vifp, struct mbuf *m) | ||||
{ | { | ||||
struct ip_moptions imo; | struct ip_moptions imo; | ||||
int error __unused; | int error __unused; | ||||
MRW_LOCK_ASSERT(); | MRW_LOCK_ASSERT(); | ||||
NET_EPOCH_ASSERT(); | |||||
imo.imo_multicast_ifp = vifp->v_ifp; | imo.imo_multicast_ifp = vifp->v_ifp; | ||||
imo.imo_multicast_ttl = mtod(m, struct ip *)->ip_ttl - 1; | imo.imo_multicast_ttl = mtod(m, struct ip *)->ip_ttl - 1; | ||||
imo.imo_multicast_loop = !!in_mcast_loop; | imo.imo_multicast_loop = !!in_mcast_loop; | ||||
imo.imo_multicast_vif = -1; | imo.imo_multicast_vif = -1; | ||||
STAILQ_INIT(&imo.imo_head); | STAILQ_INIT(&imo.imo_head); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 1,122 Lines • Show Last 20 Lines |