static bgp_attr_parse_ret_t bgp_attr_unknown(struct bgp_attr_parser_args *args)
{
	bgp_size_t total = args->total;
	struct transit *transit;
	struct peer *const peer = args->peer;
	struct attr *const attr = args->attr;
	uint8_t *const startp = args->startp;
	const uint8_t type = args->type;
	const uint8_t flag = args->flags;
	const bgp_size_t length = args->length;

	if (bgp_debug_update(peer, NULL, NULL, 1))
		zlog_debug(
			"%s Unknown attribute is received (type %d, length %d)",
			peer->host, type, length);

	/* Forward read pointer of input stream. */
	stream_forward_getp(peer->curr, length);

	/* If any of the mandatory well-known attributes are not recognized,
	   then the Error Subcode is set to Unrecognized Well-known
	   Attribute.  The Data field contains the unrecognized attribute
	   (type, length and value). */
	if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
		return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_UNREC_ATTR,
					  args->total);
	}

	/* Unrecognized non-transitive optional attributes must be quietly
	   ignored and not passed along to other BGP peers. */
	if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS))
		return BGP_ATTR_PARSE_PROCEED;

	/* If a path with recognized transitive optional attribute is
	   accepted and passed along to other BGP peers and the Partial bit
	   in the Attribute Flags octet is set to 1 by some previous AS, it
	   is not set back to 0 by the current AS. */
	SET_FLAG(*startp, BGP_ATTR_FLAG_PARTIAL);

	/* Store transitive attribute to the end of attr->transit. */
	if (!attr->transit)
		attr->transit = XCALLOC(MTYPE_TRANSIT, sizeof(struct transit));

	transit = attr->transit;

	if (transit->val)
		transit->val = XREALLOC(MTYPE_TRANSIT_VAL, transit->val,
					transit->length + total);
	else
		transit->val = XMALLOC(MTYPE_TRANSIT_VAL, total);

	memcpy(transit->val + transit->length, startp, total);
	transit->length += total;

	return BGP_ATTR_PARSE_PROCEED;
}
static bgp_attr_parse_ret_t bgp_attr_unknown(struct bgp_attr_parser_args *args)
{
	bgp_size_t total = args->total;
	struct transit *transit;
	struct peer *const peer = args->peer;
	struct attr *const attr = args->attr;
	uint8_t *const startp = args->startp;
	const uint8_t type = args->type;
	const uint8_t flag = args->flags;
	const bgp_size_t length = args->length;

	if (bgp_debug_update(peer, NULL, NULL, 1))
		zlog_debug(
			"%s Unknown attribute is received (type %d, length %d)",
			peer->host, type, length);

	 
	stream_forward_getp(peer->curr, length);

	 
	if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
		return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_UNREC_ATTR,
					  args->total);
	}

	 
	if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS))
		return BGP_ATTR_PARSE_PROCEED;

	 
	SET_FLAG(*startp, BGP_ATTR_FLAG_PARTIAL);

	 
	if (!attr->transit)
		attr->transit = XCALLOC(MTYPE_TRANSIT, sizeof(struct transit));

	transit = attr->transit;

	if (transit->val)
		transit->val = XREALLOC(MTYPE_TRANSIT_VAL, transit->val,
					transit->length + total);
	else
		transit->val = XMALLOC(MTYPE_TRANSIT_VAL, total);

	memcpy(transit->val + transit->length, startp, total);
	transit->length += total;

	return BGP_ATTR_PARSE_PROCEED;
}