FreeBSD/sys/netgraph/atm/sscop/ng_sscop.c
/*
 * Flow control message from upper layer.
 * This is very experimental:
 * If we get a message from the upper layer, that somebody has passed its
 * high water mark, we stop updating the receive window.
 * If we get a low watermark passed, then we raise the window up
 * to max - current.
 * If we get a queue status and it indicates a current below the
 * high watermark, we unstop window updates (if they are stopped) and
 * raise the window to highwater - current.
 */
Flow control message from upper layer.
This is very experimental:
If we get a message from the upper layer, that somebody has passed its
high water mark, we stop updating the receive window.
If we get a low watermark passed, then we raise the window up
to max - current.
If we get a queue status and it indicates a current below the
high watermark, we unstop window updates (if they are stopped) and
raise the window to highwater - current.
Flow control message from upper layer . This is very experimental : If we get a message from the upper layer that somebody has passed its high water mark we stop updating the receive window . If we get a low watermark passed then we raise the window up to max - current . If we get a queue status and it indicates a current below the high watermark we unstop window updates ( if they are stopped ) and raise the window to highwater - current .
static int
flow_upper(node_p node, struct ng_mesg *msg)
{
	struct ngm_queue_state *q;
	struct priv *priv = NG_NODE_PRIVATE(node);
	u_int window, space;
	if (msg->header.arglen != sizeof(struct ngm_queue_state))
		return (EINVAL);
	q = (struct ngm_queue_state *)msg->data;
	switch (msg->header.cmd) {
	  case NGM_HIGH_WATER_PASSED:
		if (priv->flow) {
			VERBOSE(priv, SSCOP_DBG_FLOW, (priv->sscop, priv,
			    "flow control stopped"));
			priv->flow = 0;
		}
		break;
	  case NGM_LOW_WATER_PASSED:
		window = sscop_window(priv->sscop, 0);
		space = q->max_queuelen_packets - q->current;
		if (space > window) {
			VERBOSE(priv, SSCOP_DBG_FLOW, (priv->sscop, priv,
			    "flow control opened window by %u messages",
			    space - window));
			(void)sscop_window(priv->sscop, space - window);
		}
		priv->flow = 1;
		break;
	  case NGM_SYNC_QUEUE_STATE:
		if (q->high_watermark <= q->current)
			break;
		window = sscop_window(priv->sscop, 0);
		if (priv->flow)
			space = q->max_queuelen_packets - q->current;
		else
			space = q->high_watermark - q->current;
		if (space > window) {
			VERBOSE(priv, SSCOP_DBG_FLOW, (priv->sscop, priv,
			    "flow control opened window by %u messages",
			    space - window));
			(void)sscop_window(priv->sscop, space - window);
		}
		priv->flow = 1;
		break;
	  default:
		return (EINVAL);
	}
	return (0);
}
static int flow_upper ( node_p node , struct ng_mesg * msg ) { struct ngm_queue_state * q ; struct priv * priv = NG_NODE_PRIVATE ( node ) ; u_int window , space ; if ( msg -> header . arglen != sizeof ( struct ngm_queue_state ) ) return ( EINVAL ) ; q = ( struct ngm_queue_state * ) msg -> data ; switch ( msg -> header . cmd ) { case NGM_HIGH_WATER_PASSED : if ( priv -> flow ) { VERBOSE ( priv , SSCOP_DBG_FLOW , ( priv -> sscop , priv , " " ) ) ; priv -> flow = 0 ; } break ; case NGM_LOW_WATER_PASSED : window = sscop_window ( priv -> sscop , 0 ) ; space = q -> max_queuelen_packets - q -> current ; if ( space > window ) { VERBOSE ( priv , SSCOP_DBG_FLOW , ( priv -> sscop , priv , " " , space - window ) ) ; ( void ) sscop_window ( priv -> sscop , space - window ) ; } priv -> flow = 1 ; break ; case NGM_SYNC_QUEUE_STATE : if ( q -> high_watermark <= q -> current ) break ; window = sscop_window ( priv -> sscop , 0 ) ; if ( priv -> flow ) space = q -> max_queuelen_packets - q -> current ; else space = q -> high_watermark - q -> current ; if ( space > window ) { VERBOSE ( priv , SSCOP_DBG_FLOW , ( priv -> sscop , priv , " " , space - window ) ) ; ( void ) sscop_window ( priv -> sscop , space - window ) ; } priv -> flow = 1 ; break ; default : return ( EINVAL ) ; } return ( 0 ) ; }
Flow control message from upper layer.
Flow control message from upper layer .