Lines Matching +full:delta +full:- +full:x +full:- +full:threshold

1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
53 * and PIM-SMv2 and PIM-DM support, advanced API support,
130 #define VIFI_INVALID ((vifi_t) -1)
183 VNET_DEFINE_STATIC(u_char *, nexpire); /* 0..mfchashsize-1 */
205 #define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */
387 if (in_hosteq(rt->mfc_origin, *o) && in mfc_find()
388 in_hosteq(rt->mfc_mcastgrp, *g) && in mfc_find()
389 buf_ring_empty(rt->mfc_stall_ring)) in mfc_find()
404 rt->mfc_stall_ring = buf_ring_alloc(MAX_UPQ, M_MRTABLE, in mfc_alloc()
406 if (rt->mfc_stall_ring == NULL) { in mfc_alloc()
427 if (so != V_ip_mrouter && sopt->sopt_name != MRT_INIT) in X_ip_mrouter_set()
431 switch (sopt->sopt_name) { in X_ip_mrouter_set()
458 if (sopt->sopt_name == MRT_ADD_MFC && in X_ip_mrouter_set()
466 sizeof(mfc) - sizeof(struct mfcctl)); in X_ip_mrouter_set()
470 if (sopt->sopt_name == MRT_ADD_MFC) in X_ip_mrouter_set()
497 if (sopt->sopt_name == MRT_ADD_BW_UPCALL) in X_ip_mrouter_set()
518 switch (sopt->sopt_name) { in X_ip_mrouter_get()
575 * returns the packet, byte, rpf-failure count for the source group provided
583 rt = mfc_find(&req->src, &req->grp); in get_sg_cnt()
586 req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff; in get_sg_cnt()
589 req->pktcnt = rt->mfc_pkt_cnt; in get_sg_cnt()
590 req->bytecnt = rt->mfc_byte_cnt; in get_sg_cnt()
591 req->wrong_if = rt->mfc_wrong_if; in get_sg_cnt()
602 vifi_t vifi = req->vifi; in get_vif_cnt()
611 req->icount = V_viftable[vifi].v_pkt_in; in get_vif_cnt()
612 req->ocount = V_viftable[vifi].v_pkt_out; in get_vif_cnt()
613 req->ibytes = V_viftable[vifi].v_bytes_in; in get_vif_cnt()
614 req->obytes = V_viftable[vifi].v_bytes_out; in get_vif_cnt()
651 if (rt->mfc_parent == vifi) { in if_detached_event()
813 * a non-sleepable lock. in X_ip_mrouter_done()
890 * - there are no vifs installed in set_api_config()
891 * - pim_assert is not enabled in set_api_config()
892 * - the MFC table is empty in set_api_config()
927 struct vif *vifp = V_viftable + vifcp->vifc_vifi; in add_vif()
933 if (vifcp->vifc_vifi >= MAXVIFS) in add_vif()
936 if (vifcp->vifc_rate_limit != 0) { in add_vif()
941 if (in_nullhost(vifcp->vifc_lcl_addr)) in add_vif()
945 if (vifcp->vifc_flags & VIFF_REGISTER) { in add_vif()
955 sin.sin_addr = vifcp->vifc_lcl_addr; in add_vif()
962 ifp = ifa->ifa_ifp; in add_vif()
967 if ((vifcp->vifc_flags & VIFF_TUNNEL) != 0) { in add_vif()
970 } else if (vifcp->vifc_flags & VIFF_REGISTER) { in add_vif()
975 V_reg_vif_num = vifcp->vifc_vifi; in add_vif()
978 if ((ifp->if_flags & IFF_MULTICAST) == 0) in add_vif()
989 if (!in_nullhost(vifp->v_lcl_addr)) { in add_vif()
998 vifp->v_flags = vifcp->vifc_flags; in add_vif()
999 vifp->v_threshold = vifcp->vifc_threshold; in add_vif()
1000 vifp->v_lcl_addr = vifcp->vifc_lcl_addr; in add_vif()
1001 vifp->v_rmt_addr = vifcp->vifc_rmt_addr; in add_vif()
1002 vifp->v_ifp = ifp; in add_vif()
1004 vifp->v_pkt_in = 0; in add_vif()
1005 vifp->v_pkt_out = 0; in add_vif()
1006 vifp->v_bytes_in = 0; in add_vif()
1007 vifp->v_bytes_out = 0; in add_vif()
1008 sprintf(vifp->v_spin_name, "BM[%d] spin", vifcp->vifc_vifi); in add_vif()
1009 mtx_init(&vifp->v_spin, vifp->v_spin_name, NULL, MTX_SPIN); in add_vif()
1012 if (V_numvifs <= vifcp->vifc_vifi) in add_vif()
1013 V_numvifs = vifcp->vifc_vifi + 1; in add_vif()
1017 CTR4(KTR_IPMF, "%s: add vif %d laddr 0x%08x thresh %x", __func__, in add_vif()
1018 (int)vifcp->vifc_vifi, ntohl(vifcp->vifc_lcl_addr.s_addr), in add_vif()
1019 (int)vifcp->vifc_threshold); in add_vif()
1041 if (in_nullhost(vifp->v_lcl_addr)) { in del_vif_locked()
1045 if (!(vifp->v_flags & (VIFF_TUNNEL | VIFF_REGISTER))) in del_vif_locked()
1046 *ifp_multi_leave = vifp->v_ifp; in del_vif_locked()
1048 if (vifp->v_flags & VIFF_REGISTER) { in del_vif_locked()
1050 if (vifp->v_ifp) { in del_vif_locked()
1051 if (vifp->v_ifp == V_multicast_register_if) in del_vif_locked()
1053 *ifp_free = vifp->v_ifp; in del_vif_locked()
1057 mtx_destroy(&vifp->v_spin); in del_vif_locked()
1064 for (vifi = V_numvifs; vifi > 0; vifi--) in del_vif_locked()
1065 if (!in_nullhost(V_viftable[vifi-1].v_lcl_addr)) in del_vif_locked()
1099 rt->mfc_parent = mfccp->mfcc_parent; in update_mfc_params()
1101 rt->mfc_ttls[i] = mfccp->mfcc_ttls[i]; in update_mfc_params()
1102 rt->mfc_flags[i] = mfccp->mfcc_flags[i] & V_mrt_api_config & in update_mfc_params()
1107 rt->mfc_rp = mfccp->mfcc_rp; in update_mfc_params()
1109 rt->mfc_rp.s_addr = INADDR_ANY; in update_mfc_params()
1118 rt->mfc_origin = mfccp->mfcc_origin; in init_mfc_params()
1119 rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp; in init_mfc_params()
1123 /* initialize pkt counters per src-grp */ in init_mfc_params()
1124 rt->mfc_pkt_cnt = 0; in init_mfc_params()
1125 rt->mfc_byte_cnt = 0; in init_mfc_params()
1126 rt->mfc_wrong_if = 0; in init_mfc_params()
1127 timevalclear(&rt->mfc_last_assert); in init_mfc_params()
1137 free_bw_list(rt->mfc_bw_meter_leq); in expire_mfc()
1138 free_bw_list(rt->mfc_bw_meter_geq); in expire_mfc()
1140 while (!buf_ring_empty(rt->mfc_stall_ring)) { in expire_mfc()
1141 rte = buf_ring_dequeue_mc(rt->mfc_stall_ring); in expire_mfc()
1143 m_freem(rte->m); in expire_mfc()
1147 buf_ring_free(rt->mfc_stall_ring, M_MRTABLE); in expire_mfc()
1166 rt = mfc_find(&mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp); in add_mfc()
1170 CTR4(KTR_IPMF, "%s: update mfc orig 0x%08x group %lx parent %x", in add_mfc()
1171 __func__, ntohl(mfccp->mfcc_origin.s_addr), in add_mfc()
1172 (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr), in add_mfc()
1173 mfccp->mfcc_parent); in add_mfc()
1183 hash = MFCHASH(mfccp->mfcc_origin, mfccp->mfcc_mcastgrp); in add_mfc()
1186 if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && in add_mfc()
1187 in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp) && in add_mfc()
1188 !buf_ring_empty(rt->mfc_stall_ring)) { in add_mfc()
1190 "%s: add mfc orig 0x%08x group %lx parent %x qh %p", in add_mfc()
1191 __func__, ntohl(mfccp->mfcc_origin.s_addr), in add_mfc()
1192 (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr), in add_mfc()
1193 mfccp->mfcc_parent, in add_mfc()
1194 rt->mfc_stall_ring); in add_mfc()
1199 rt->mfc_expire = 0; /* Don't clean this guy up */ in add_mfc()
1200 V_nexpire[hash]--; in add_mfc()
1203 while (!buf_ring_empty(rt->mfc_stall_ring)) { in add_mfc()
1204 rte = buf_ring_dequeue_mc(rt->mfc_stall_ring); in add_mfc()
1205 if (rte->ifp != NULL) in add_mfc()
1206 ip_mdq(rte->m, rte->ifp, rt, -1); in add_mfc()
1207 m_freem(rte->m); in add_mfc()
1220 if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && in add_mfc()
1221 in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp)) { in add_mfc()
1223 if (rt->mfc_expire) in add_mfc()
1224 V_nexpire[hash]--; in add_mfc()
1225 rt->mfc_expire = 0; in add_mfc()
1239 rt->mfc_expire = 0; in add_mfc()
1240 rt->mfc_bw_meter_leq = NULL; in add_mfc()
1241 rt->mfc_bw_meter_geq = NULL; in add_mfc()
1263 origin = mfccp->mfcc_origin; in del_mfc()
1264 mcastgrp = mfccp->mfcc_mcastgrp; in del_mfc()
1266 CTR3(KTR_IPMF, "%s: delete mfc orig 0x%08x group %lx", __func__, in del_mfc()
1272 if (in_hosteq(rt->mfc_origin, origin) && in del_mfc()
1273 in_hosteq(rt->mfc_mcastgrp, mcastgrp)) in del_mfc()
1295 SOCKBUF_LOCK(&s->so_rcv); in socket_send()
1296 if (sbappendaddr_locked(&s->so_rcv, (struct sockaddr *)src, mm, in socket_send()
1304 return -1; in socket_send()
1314 * erroneous, in which case a non-zero return value tells the caller to
1334 CTR3(KTR_IPMF, "ip_mforward: delete mfc orig 0x%08x group %lx ifp %p", in X_ip_mforward()
1335 ntohl(ip->ip_src.s_addr), (u_long)ntohl(ip->ip_dst.s_addr), ifp); in X_ip_mforward()
1337 if (ip->ip_hl < (sizeof(struct ip) + TUNNEL_LEN) >> 2 || in X_ip_mforward()
1345 * Packet arrived through a source-route tunnel. in X_ip_mforward()
1346 * Source-route tunnels are no longer supported. in X_ip_mforward()
1355 if (imo && ((vifi = imo->imo_multicast_vif) < V_numvifs)) { in X_ip_mforward()
1356 if (ip->ip_ttl < MAXTTL) in X_ip_mforward()
1357 ip->ip_ttl++; /* compensate for -1 in *_send routines */ in X_ip_mforward()
1364 * Don't forward a packet with time-to-live of zero or one, in X_ip_mforward()
1365 * or a packet destined to a local-only group. in X_ip_mforward()
1367 if (ip->ip_ttl <= 1 || IN_LOCAL_GROUP(ntohl(ip->ip_dst.s_addr))) { in X_ip_mforward()
1377 rt = mfc_find(&ip->ip_src, &ip->ip_dst); in X_ip_mforward()
1381 error = ip_mdq(m, ifp, rt, -1); in X_ip_mforward()
1402 hlen = ip->ip_hl << 2; in X_ip_mforward()
1406 CTR2(KTR_IPMF, "ip_mforward: no mfc for (0x%08x,%lx)", in X_ip_mforward()
1407 ntohl(ip->ip_src.s_addr), (u_long)ntohl(ip->ip_dst.s_addr)); in X_ip_mforward()
1421 if (mb0 && (!M_WRITABLE(mb0) || mb0->m_len < hlen)) in X_ip_mforward()
1430 hash = MFCHASH(ip->ip_src, ip->ip_dst); in X_ip_mforward()
1433 if (in_hosteq(ip->ip_src, rt->mfc_origin) && in X_ip_mforward()
1434 in_hosteq(ip->ip_dst, rt->mfc_mcastgrp) && in X_ip_mforward()
1435 !buf_ring_empty(rt->mfc_stall_ring)) in X_ip_mforward()
1471 im->im_msgtype = IGMPMSG_NOCACHE; in X_ip_mforward()
1472 im->im_mbz = 0; in X_ip_mforward()
1473 im->im_vif = vifi; in X_ip_mforward()
1477 k_igmpsrc.sin_addr = ip->ip_src; in X_ip_mforward()
1489 rt->mfc_origin.s_addr = ip->ip_src.s_addr; in X_ip_mforward()
1490 rt->mfc_mcastgrp.s_addr = ip->ip_dst.s_addr; in X_ip_mforward()
1491 rt->mfc_expire = UPCALL_EXPIRE; in X_ip_mforward()
1494 rt->mfc_ttls[i] = 0; in X_ip_mforward()
1495 rt->mfc_flags[i] = 0; in X_ip_mforward()
1497 rt->mfc_parent = -1; in X_ip_mforward()
1500 rt->mfc_rp.s_addr = INADDR_ANY; in X_ip_mforward()
1501 rt->mfc_bw_meter_leq = NULL; in X_ip_mforward()
1502 rt->mfc_bw_meter_geq = NULL; in X_ip_mforward()
1504 /* initialize pkt counters per src-grp */ in X_ip_mforward()
1505 rt->mfc_pkt_cnt = 0; in X_ip_mforward()
1506 rt->mfc_byte_cnt = 0; in X_ip_mforward()
1507 rt->mfc_wrong_if = 0; in X_ip_mforward()
1508 timevalclear(&rt->mfc_last_assert); in X_ip_mforward()
1510 buf_ring_enqueue(rt->mfc_stall_ring, rte); in X_ip_mforward()
1516 if (buf_ring_full(rt->mfc_stall_ring)) { in X_ip_mforward()
1524 buf_ring_enqueue(rt->mfc_stall_ring, rte); in X_ip_mforward()
1527 rte->m = mb0; in X_ip_mforward()
1528 rte->ifp = ifp; in X_ip_mforward()
1554 if (buf_ring_empty(rt->mfc_stall_ring)) in expire_upcalls()
1557 if (rt->mfc_expire == 0 || --rt->mfc_expire > 0) in expire_upcalls()
1562 (u_long)ntohl(rt->mfc_origin.s_addr), in expire_upcalls()
1563 (u_long)ntohl(rt->mfc_mcastgrp.s_addr)); in expire_upcalls()
1583 int plen = ntohs(ip->ip_len); in ip_mdq()
1590 * If xmt_vif is not -1, send on only the requested vif. in ip_mdq()
1592 * (since vifi_t is u_short, -1 becomes MAXUSHORT, which > numvifs.) in ip_mdq()
1605 vifi = rt->mfc_parent; in ip_mdq()
1610 ++rt->mfc_wrong_if; in ip_mdq()
1615 * XXX: A PIM-SM router needs the WRONGVIF detection so it in ip_mdq()
1630 if (rt->mfc_flags[vifi] & MRT_MFC_FLAGS_DISABLE_WRONGVIF) in ip_mdq()
1633 if (ratecheck(&rt->mfc_last_assert, &pim_assert_interval)) { in ip_mdq()
1636 int hlen = ip->ip_hl << 2; in ip_mdq()
1639 if (mm && (!M_WRITABLE(mm) || mm->m_len < hlen)) in ip_mdq()
1645 im->im_msgtype = IGMPMSG_WRONGVIF; in ip_mdq()
1646 im->im_mbz = 0; in ip_mdq()
1647 im->im_vif = vifi; in ip_mdq()
1651 k_igmpsrc.sin_addr = im->im_src; in ip_mdq()
1664 if (in_hosteq(ip->ip_src, V_viftable[vifi].v_lcl_addr)) { in ip_mdq()
1673 rt->mfc_pkt_cnt++; in ip_mdq()
1674 rt->mfc_byte_cnt += plen; in ip_mdq()
1679 * - the ttl exceeds the vif's threshold in ip_mdq()
1680 * - there are group members downstream on interface in ip_mdq()
1683 if ((rt->mfc_ttls[vifi] > 0) && (ip->ip_ttl > rt->mfc_ttls[vifi])) { in ip_mdq()
1693 * Perform upcall-related bw measuring. in ip_mdq()
1695 if ((rt->mfc_bw_meter_geq != NULL) || (rt->mfc_bw_meter_leq != NULL)) { in ip_mdq()
1696 struct bw_meter *x; in ip_mdq() local
1700 /* Process meters for Greater-or-EQual case */ in ip_mdq()
1701 for (x = rt->mfc_bw_meter_geq; x != NULL; x = x->bm_mfc_next) in ip_mdq()
1702 bw_meter_geq_receive_packet(x, plen, &now); in ip_mdq()
1704 /* Process meters for Lower-or-EQual case */ in ip_mdq()
1705 for (x = rt->mfc_bw_meter_leq; x != NULL; x = x->bm_mfc_next) { in ip_mdq()
1712 mtx_lock_spin(&x->bm_spin); in ip_mdq()
1713 x->bm_measured.b_packets++; in ip_mdq()
1714 x->bm_measured.b_bytes += plen; in ip_mdq()
1715 mtx_unlock_spin(&x->bm_spin); in ip_mdq()
1766 int hlen = ip->ip_hl << 2; in phyint_send()
1777 if (mb_copy && (!M_WRITABLE(mb_copy) || mb_copy->m_len < hlen)) in phyint_send()
1794 imo.imo_multicast_ifp = vifp->v_ifp; in send_packet()
1795 imo.imo_multicast_ttl = mtod(m, struct ip *)->ip_ttl - 1; in send_packet()
1797 imo.imo_multicast_vif = -1; in send_packet()
1801 * Re-entrancy should not be a problem here, because in send_packet()
1808 (ptrdiff_t)(vifp - V_viftable), error); in send_packet()
1845 * Define common interface for timeval-related methods
1856 if (req->bu_flags & BW_UPCALL_UNIT_PACKETS) in compute_bw_meter_flags()
1858 if (req->bu_flags & BW_UPCALL_UNIT_BYTES) in compute_bw_meter_flags()
1860 if (req->bu_flags & BW_UPCALL_GEQ) in compute_bw_meter_flags()
1862 if (req->bu_flags & BW_UPCALL_LEQ) in compute_bw_meter_flags()
1871 struct bw_meter *x = arg; in expire_bw_meter_leq() local
1878 CURVNET_SET((struct vnet *)x->arg); in expire_bw_meter_leq()
1885 if (((x->bm_flags & BW_METER_UNIT_PACKETS) && in expire_bw_meter_leq()
1886 (x->bm_measured.b_packets <= x->bm_threshold.b_packets)) || in expire_bw_meter_leq()
1887 ((x->bm_flags & BW_METER_UNIT_BYTES) && in expire_bw_meter_leq()
1888 (x->bm_measured.b_bytes <= x->bm_threshold.b_bytes))) { in expire_bw_meter_leq()
1890 bw_meter_prepare_upcall(x, &now); in expire_bw_meter_leq()
1897 x->bm_start_time = now; in expire_bw_meter_leq()
1901 mtx_lock_spin(&x->bm_spin); in expire_bw_meter_leq()
1902 x->bm_measured.b_bytes = 0; in expire_bw_meter_leq()
1903 x->bm_measured.b_packets = 0; in expire_bw_meter_leq()
1904 mtx_unlock_spin(&x->bm_spin); in expire_bw_meter_leq()
1906 callout_schedule(&x->bm_meter_callout, tvtohz(&x->bm_threshold.b_time)); in expire_bw_meter_leq()
1918 struct timeval delta = { BW_UPCALL_THRESHOLD_INTERVAL_MIN_SEC, in add_bw_upcall() local
1921 struct bw_meter *x, **bwm_ptr; in add_bw_upcall() local
1928 if (!(req->bu_flags & (BW_UPCALL_UNIT_PACKETS | BW_UPCALL_UNIT_BYTES))) in add_bw_upcall()
1930 if (!(req->bu_flags & (BW_UPCALL_GEQ | BW_UPCALL_LEQ))) in add_bw_upcall()
1932 if ((req->bu_flags & (BW_UPCALL_GEQ | BW_UPCALL_LEQ)) == (BW_UPCALL_GEQ | BW_UPCALL_LEQ)) in add_bw_upcall()
1935 /* Test if the threshold time interval is valid */ in add_bw_upcall()
1936 if (BW_TIMEVALCMP(&req->bu_threshold.b_time, &delta, <)) in add_bw_upcall()
1945 mfc = mfc_find(&req->bu_src, &req->bu_dst); in add_bw_upcall()
1952 if (req->bu_flags & BW_UPCALL_GEQ) in add_bw_upcall()
1953 bwm_ptr = &mfc->mfc_bw_meter_geq; in add_bw_upcall()
1955 bwm_ptr = &mfc->mfc_bw_meter_leq; in add_bw_upcall()
1957 for (x = *bwm_ptr; x != NULL; x = x->bm_mfc_next) { in add_bw_upcall()
1958 if ((BW_TIMEVALCMP(&x->bm_threshold.b_time, in add_bw_upcall()
1959 &req->bu_threshold.b_time, ==)) in add_bw_upcall()
1960 && (x->bm_threshold.b_packets in add_bw_upcall()
1961 == req->bu_threshold.b_packets) in add_bw_upcall()
1962 && (x->bm_threshold.b_bytes in add_bw_upcall()
1963 == req->bu_threshold.b_bytes) in add_bw_upcall()
1964 && (x->bm_flags & BW_METER_USER_FLAGS) in add_bw_upcall()
1972 x = malloc(sizeof(*x), M_BWMETER, M_ZERO | M_NOWAIT); in add_bw_upcall()
1973 if (x == NULL) { in add_bw_upcall()
1979 x->bm_threshold.b_time = req->bu_threshold.b_time; in add_bw_upcall()
1981 x->bm_start_time = now; in add_bw_upcall()
1982 x->bm_threshold.b_packets = req->bu_threshold.b_packets; in add_bw_upcall()
1983 x->bm_threshold.b_bytes = req->bu_threshold.b_bytes; in add_bw_upcall()
1984 x->bm_measured.b_packets = 0; in add_bw_upcall()
1985 x->bm_measured.b_bytes = 0; in add_bw_upcall()
1986 x->bm_flags = flags; in add_bw_upcall()
1987 x->bm_time_next = NULL; in add_bw_upcall()
1988 x->bm_mfc = mfc; in add_bw_upcall()
1989 x->arg = curvnet; in add_bw_upcall()
1990 sprintf(x->bm_spin_name, "BM spin %p", x); in add_bw_upcall()
1991 mtx_init(&x->bm_spin, x->bm_spin_name, NULL, MTX_SPIN); in add_bw_upcall()
1994 if (req->bu_flags & BW_UPCALL_LEQ) { in add_bw_upcall()
1995 callout_init_rw(&x->bm_meter_callout, &mrouter_lock, CALLOUT_SHAREDLOCK); in add_bw_upcall()
1996 callout_reset(&x->bm_meter_callout, tvtohz(&x->bm_threshold.b_time), in add_bw_upcall()
1997 expire_bw_meter_leq, x); in add_bw_upcall()
2001 x->bm_mfc_next = *bwm_ptr; in add_bw_upcall()
2002 *bwm_ptr = x; in add_bw_upcall()
2013 struct bw_meter *x = list; in free_bw_list() local
2016 if (x->bm_flags & BW_METER_LEQ) { in free_bw_list()
2017 callout_drain(&x->bm_meter_callout); in free_bw_list()
2018 mtx_destroy(&x->bm_spin); in free_bw_list()
2021 list = list->bm_mfc_next; in free_bw_list()
2022 free(x, M_BWMETER); in free_bw_list()
2033 struct bw_meter *x, **bwm_ptr; in del_bw_upcall() local
2041 mfc = mfc_find(&req->bu_src, &req->bu_dst); in del_bw_upcall()
2045 } else if (req->bu_flags & BW_UPCALL_DELETE_ALL) { in del_bw_upcall()
2052 list = mfc->mfc_bw_meter_leq; in del_bw_upcall()
2053 mfc->mfc_bw_meter_leq = NULL; in del_bw_upcall()
2057 list = mfc->mfc_bw_meter_geq; in del_bw_upcall()
2058 mfc->mfc_bw_meter_geq = NULL; in del_bw_upcall()
2069 if (req->bu_flags & BW_UPCALL_GEQ) in del_bw_upcall()
2070 bwm_ptr = &mfc->mfc_bw_meter_geq; in del_bw_upcall()
2072 bwm_ptr = &mfc->mfc_bw_meter_leq; in del_bw_upcall()
2075 for (prev = NULL, x = *bwm_ptr; x != NULL; in del_bw_upcall()
2076 prev = x, x = x->bm_mfc_next) { in del_bw_upcall()
2077 if ((BW_TIMEVALCMP(&x->bm_threshold.b_time, &req->bu_threshold.b_time, ==)) && in del_bw_upcall()
2078 (x->bm_threshold.b_packets == req->bu_threshold.b_packets) && in del_bw_upcall()
2079 (x->bm_threshold.b_bytes == req->bu_threshold.b_bytes) && in del_bw_upcall()
2080 (x->bm_flags & BW_METER_USER_FLAGS) == flags) in del_bw_upcall()
2083 if (x != NULL) { /* Delete entry from the list for this MFC */ in del_bw_upcall()
2085 prev->bm_mfc_next = x->bm_mfc_next; /* remove from middle*/ in del_bw_upcall()
2087 *bwm_ptr = x->bm_mfc_next;/* new head of list */ in del_bw_upcall()
2089 if (req->bu_flags & BW_UPCALL_LEQ) in del_bw_upcall()
2090 callout_stop(&x->bm_meter_callout); in del_bw_upcall()
2094 free(x, M_BWMETER); in del_bw_upcall()
2108 bw_meter_geq_receive_packet(struct bw_meter *x, int plen, struct timeval *nowp) in bw_meter_geq_receive_packet() argument
2110 struct timeval delta; in bw_meter_geq_receive_packet() local
2114 delta = *nowp; in bw_meter_geq_receive_packet()
2115 BW_TIMEVALDECR(&delta, &x->bm_start_time); in bw_meter_geq_receive_packet()
2122 if (BW_TIMEVALCMP(&delta, &x->bm_threshold.b_time, >)) { in bw_meter_geq_receive_packet()
2124 x->bm_start_time = *nowp; in bw_meter_geq_receive_packet()
2125 x->bm_measured.b_packets = 0; in bw_meter_geq_receive_packet()
2126 x->bm_measured.b_bytes = 0; in bw_meter_geq_receive_packet()
2127 x->bm_flags &= ~BW_METER_UPCALL_DELIVERED; in bw_meter_geq_receive_packet()
2131 x->bm_measured.b_packets++; in bw_meter_geq_receive_packet()
2132 x->bm_measured.b_bytes += plen; in bw_meter_geq_receive_packet()
2137 if (!(x->bm_flags & BW_METER_UPCALL_DELIVERED)) { in bw_meter_geq_receive_packet()
2138 if (((x->bm_flags & BW_METER_UNIT_PACKETS) && in bw_meter_geq_receive_packet()
2139 (x->bm_measured.b_packets >= x->bm_threshold.b_packets)) || in bw_meter_geq_receive_packet()
2140 ((x->bm_flags & BW_METER_UNIT_BYTES) && in bw_meter_geq_receive_packet()
2141 (x->bm_measured.b_bytes >= x->bm_threshold.b_bytes))) { in bw_meter_geq_receive_packet()
2143 bw_meter_prepare_upcall(x, nowp); in bw_meter_geq_receive_packet()
2144 x->bm_flags |= BW_METER_UPCALL_DELIVERED; in bw_meter_geq_receive_packet()
2150 * Prepare a bandwidth-related upcall
2153 bw_meter_prepare_upcall(struct bw_meter *x, struct timeval *nowp) in bw_meter_prepare_upcall() argument
2155 struct timeval delta; in bw_meter_prepare_upcall() local
2163 delta = *nowp; in bw_meter_prepare_upcall()
2164 BW_TIMEVALDECR(&delta, &x->bm_start_time); in bw_meter_prepare_upcall()
2174 u->bu_src = x->bm_mfc->mfc_origin; in bw_meter_prepare_upcall()
2175 u->bu_dst = x->bm_mfc->mfc_mcastgrp; in bw_meter_prepare_upcall()
2176 u->bu_threshold.b_time = x->bm_threshold.b_time; in bw_meter_prepare_upcall()
2177 u->bu_threshold.b_packets = x->bm_threshold.b_packets; in bw_meter_prepare_upcall()
2178 u->bu_threshold.b_bytes = x->bm_threshold.b_bytes; in bw_meter_prepare_upcall()
2179 u->bu_measured.b_time = delta; in bw_meter_prepare_upcall()
2180 u->bu_measured.b_packets = x->bm_measured.b_packets; in bw_meter_prepare_upcall()
2181 u->bu_measured.b_bytes = x->bm_measured.b_bytes; in bw_meter_prepare_upcall()
2182 u->bu_flags = 0; in bw_meter_prepare_upcall()
2183 if (x->bm_flags & BW_METER_UNIT_PACKETS) in bw_meter_prepare_upcall()
2184 u->bu_flags |= BW_UPCALL_UNIT_PACKETS; in bw_meter_prepare_upcall()
2185 if (x->bm_flags & BW_METER_UNIT_BYTES) in bw_meter_prepare_upcall()
2186 u->bu_flags |= BW_UPCALL_UNIT_BYTES; in bw_meter_prepare_upcall()
2187 if (x->bm_flags & BW_METER_GEQ) in bw_meter_prepare_upcall()
2188 u->bu_flags |= BW_UPCALL_GEQ; in bw_meter_prepare_upcall()
2189 if (x->bm_flags & BW_METER_LEQ) in bw_meter_prepare_upcall()
2190 u->bu_flags |= BW_UPCALL_LEQ; in bw_meter_prepare_upcall()
2199 * Send the pending bandwidth-related upcalls
2289 in_nullhost(rt->mfc_rp)) in pim_register_send()
2301 mb_copy = mm->m_nextpkt; in pim_register_send()
2302 mm->m_nextpkt = 0; in pim_register_send()
2306 if ((V_mrt_api_config & MRT_MFC_RP) && !in_nullhost(rt->mfc_rp)) { in pim_register_send()
2329 if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { in pim_register_prepare()
2331 m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; in pim_register_prepare()
2341 mb_copy = m_pullup(mb_copy, ip->ip_hl << 2); in pim_register_prepare()
2347 --ip->ip_ttl; in pim_register_prepare()
2350 mtu = 0xffff - sizeof(pim_encap_iphdr) - sizeof(pim_encap_pimhdr); in pim_register_prepare()
2352 if (ntohs(ip->ip_len) <= mtu) { in pim_register_prepare()
2354 ip->ip_sum = 0; in pim_register_prepare()
2355 ip->ip_sum = in_cksum(mb_copy, ip->ip_hl << 2); in pim_register_prepare()
2358 mb_copy->m_pkthdr.csum_flags |= CSUM_IP; in pim_register_prepare()
2368 * Send an upcall with the data packet to the user-level process.
2375 int len = ntohs(ip->ip_len); in pim_register_send_upcall()
2389 mb_first->m_data += max_linkhdr; in pim_register_send_upcall()
2390 mb_first->m_pkthdr.len = len + sizeof(struct igmpmsg); in pim_register_send_upcall()
2391 mb_first->m_len = sizeof(struct igmpmsg); in pim_register_send_upcall()
2392 mb_first->m_next = mb_copy; in pim_register_send_upcall()
2396 im->im_msgtype = IGMPMSG_WHOLEPKT; in pim_register_send_upcall()
2397 im->im_mbz = 0; in pim_register_send_upcall()
2398 im->im_vif = vifp - V_viftable; in pim_register_send_upcall()
2399 im->im_src = ip->ip_src; in pim_register_send_upcall()
2400 im->im_dst = ip->ip_dst; in pim_register_send_upcall()
2402 k_igmpsrc.sin_addr = ip->ip_src; in pim_register_send_upcall()
2429 int len = ntohs(ip->ip_len); in pim_register_send_rp()
2430 vifi_t vifi = rt->mfc_parent; in pim_register_send_rp()
2447 mb_first->m_data += max_linkhdr; in pim_register_send_rp()
2448 mb_first->m_len = sizeof(pim_encap_iphdr) + sizeof(pim_encap_pimhdr); in pim_register_send_rp()
2449 mb_first->m_next = mb_copy; in pim_register_send_rp()
2451 mb_first->m_pkthdr.len = len + mb_first->m_len; in pim_register_send_rp()
2458 ip_outer->ip_len = htons(len + sizeof(pim_encap_iphdr) + in pim_register_send_rp()
2460 ip_outer->ip_src = V_viftable[vifi].v_lcl_addr; in pim_register_send_rp()
2461 ip_outer->ip_dst = rt->mfc_rp; in pim_register_send_rp()
2466 ip_outer->ip_tos = ip->ip_tos; in pim_register_send_rp()
2467 if (ip->ip_off & htons(IP_DF)) in pim_register_send_rp()
2468 ip_outer->ip_off |= htons(IP_DF); in pim_register_send_rp()
2473 /* If the iif crosses a border, set the Border-bit */ in pim_register_send_rp()
2474 if (rt->mfc_flags[vifi] & MRT_MFC_FLAGS_BORDER_VIF & V_mrt_api_config) in pim_register_send_rp()
2475 pimhdr->flags |= htonl(PIM_BORDER_REGISTER); in pim_register_send_rp()
2477 mb_first->m_data += sizeof(pim_encap_iphdr); in pim_register_send_rp()
2478 pimhdr->pim.pim_cksum = in_cksum(mb_first, sizeof(pim_encap_pimhdr)); in pim_register_send_rp()
2479 mb_first->m_data -= sizeof(pim_encap_iphdr); in pim_register_send_rp()
2505 * PIM-SMv2 and PIM-DM messages processing.
2509 * (used by PIM-SM): the PIM header is stripped off, and the inner packet
2519 int datalen = ntohs(ip->ip_len) - iphlen; in pim_input()
2531 CTR3(KTR_IPMF, "%s: short packet (%d) from 0x%08x", in pim_input()
2532 __func__, datalen, ntohl(ip->ip_src.s_addr)); in pim_input()
2550 if (m->m_len < minlen && (m = m_pullup(m, minlen)) == NULL) { in pim_input()
2557 ip_tos = ip->ip_tos; in pim_input()
2560 m->m_data += iphlen; in pim_input()
2561 m->m_len -= iphlen; in pim_input()
2571 if (PIM_VT_T(pim->pim_vt) == PIM_REGISTER && in_cksum(m, PIM_MINLEN) == 0) { in pim_input()
2581 if (PIM_VT_V(pim->pim_vt) < PIM_VERSION) { in pim_input()
2584 (int)PIM_VT_V(pim->pim_vt), PIM_VERSION); in pim_input()
2590 m->m_data -= iphlen; in pim_input()
2591 m->m_len += iphlen; in pim_input()
2593 if (PIM_VT_T(pim->pim_vt) == PIM_REGISTER) { in pim_input()
2631 CTR3(KTR_IPMF, "%s: register: encap ip src 0x%08x len %d", in pim_input()
2632 __func__, ntohl(encap_ip->ip_src.s_addr), in pim_input()
2633 ntohs(encap_ip->ip_len)); in pim_input()
2636 if (encap_ip->ip_v != IPVERSION) { in pim_input()
2644 if (!IN_MULTICAST(ntohl(encap_ip->ip_dst.s_addr))) { in pim_input()
2646 CTR2(KTR_IPMF, "%s: bad encap ip dest 0x%08x", __func__, in pim_input()
2647 ntohl(encap_ip->ip_dst.s_addr)); in pim_input()
2659 if (encap_ip->ip_tos != ip_tos) { in pim_input()
2660 /* Outer TOS -> inner TOS */ in pim_input()
2661 encap_ip->ip_tos = ip_tos; in pim_input()
2665 m->m_data += (iphlen + PIM_MINLEN); in pim_input()
2666 m->m_len -= (iphlen + PIM_MINLEN); in pim_input()
2668 encap_ip->ip_sum = 0; in pim_input()
2669 encap_ip->ip_sum = in_cksum(m, encap_ip->ip_hl << 2); in pim_input()
2672 m->m_data -= (iphlen + PIM_MINLEN); in pim_input()
2673 m->m_len += (iphlen + PIM_MINLEN); in pim_input()
2682 * XXX: here m->m_data points to the outer IP header. in pim_input()
2694 PIMSTAT_ADD(pims_rcv_registers_bytes, ntohs(encap_ip->ip_len)); in pim_input()
2704 (u_long)ntohl(encap_ip->ip_src.s_addr), in pim_input()
2705 (u_long)ntohl(encap_ip->ip_dst.s_addr), in pim_input()
2719 * outer IP header, PIM header, PIM-Register header and the in pim_input()
2733 if (req->newptr) in sysctl_mfctable()
2767 if (req->newptr) in sysctl_viflist()
2776 /* Copy out user-visible portion of vif entry. */ in sysctl_viflist()
2869 * Typically module unload happens after the user-level in ip_mroute_modevent()