* Add a bw_meter entry */
| 1759 | * Add a bw_meter entry |
| 1760 | */ |
| 1761 | static int |
| 1762 | add_bw_upcall(struct bw_upcall *req) |
| 1763 | { |
| 1764 | struct mfc *mfc; |
| 1765 | struct timeval delta = { BW_UPCALL_THRESHOLD_INTERVAL_MIN_SEC, |
| 1766 | BW_UPCALL_THRESHOLD_INTERVAL_MIN_USEC }; |
| 1767 | struct timeval now; |
| 1768 | struct bw_meter *x; |
| 1769 | uint32_t flags; |
| 1770 | |
| 1771 | if (!(V_mrt_api_config & MRT_MFC_BW_UPCALL)) |
| 1772 | return EOPNOTSUPP; |
| 1773 | |
| 1774 | /* Test if the flags are valid */ |
| 1775 | if (!(req->bu_flags & (BW_UPCALL_UNIT_PACKETS | BW_UPCALL_UNIT_BYTES))) |
| 1776 | return EINVAL; |
| 1777 | if (!(req->bu_flags & (BW_UPCALL_GEQ | BW_UPCALL_LEQ))) |
| 1778 | return EINVAL; |
| 1779 | if ((req->bu_flags & (BW_UPCALL_GEQ | BW_UPCALL_LEQ)) |
| 1780 | == (BW_UPCALL_GEQ | BW_UPCALL_LEQ)) |
| 1781 | return EINVAL; |
| 1782 | |
| 1783 | /* Test if the threshold time interval is valid */ |
| 1784 | if (BW_TIMEVALCMP(&req->bu_threshold.b_time, &delta, <)) |
| 1785 | return EINVAL; |
| 1786 | |
| 1787 | flags = compute_bw_meter_flags(req); |
| 1788 | |
| 1789 | /* |
| 1790 | * Find if we have already same bw_meter entry |
| 1791 | */ |
| 1792 | MFC_LOCK(); |
| 1793 | mfc = mfc_find(&req->bu_src, &req->bu_dst); |
| 1794 | if (mfc == NULL) { |
| 1795 | MFC_UNLOCK(); |
| 1796 | return EADDRNOTAVAIL; |
| 1797 | } |
| 1798 | for (x = mfc->mfc_bw_meter; x != NULL; x = x->bm_mfc_next) { |
| 1799 | if ((BW_TIMEVALCMP(&x->bm_threshold.b_time, |
| 1800 | &req->bu_threshold.b_time, ==)) && |
| 1801 | (x->bm_threshold.b_packets == req->bu_threshold.b_packets) && |
| 1802 | (x->bm_threshold.b_bytes == req->bu_threshold.b_bytes) && |
| 1803 | (x->bm_flags & BW_METER_USER_FLAGS) == flags) { |
| 1804 | MFC_UNLOCK(); |
| 1805 | return 0; /* XXX Already installed */ |
| 1806 | } |
| 1807 | } |
| 1808 | |
| 1809 | /* Allocate the new bw_meter entry */ |
| 1810 | x = (struct bw_meter *)malloc(sizeof(*x), M_BWMETER, M_NOWAIT); |
| 1811 | if (x == NULL) { |
| 1812 | MFC_UNLOCK(); |
| 1813 | return ENOBUFS; |
| 1814 | } |
| 1815 | |
| 1816 | /* Set the new bw_meter entry */ |
| 1817 | x->bm_threshold.b_time = req->bu_threshold.b_time; |
| 1818 | microtime(&now); |
no test coverage detected