static int build_gre_transport_data()

in drivers/vector_transports.c [241:300]


static int build_gre_transport_data(struct vector_private *vp)
{
	struct uml_gre_data *td;
	int temp_int;
	int temp_rx;
	int temp_tx;

	vp->transport_data = kmalloc(sizeof(struct uml_gre_data), GFP_KERNEL);
	if (vp->transport_data == NULL)
		return -ENOMEM;
	td = vp->transport_data;
	td->sequence = 0;

	td->expected_header.arptype = GRE_IRB;
	td->expected_header.header = 0;

	vp->form_header = &gre_form_header;
	vp->verify_header = &gre_verify_header;
	vp->header_size = 4;
	td->key_offset = 4;
	td->sequence_offset = 4;
	td->checksum_offset = 4;

	td->ipv6 = false;
	if (get_uint_param(vp->parsed, "v6", &temp_int)) {
		if (temp_int > 0)
			td->ipv6 = true;
	}
	td->key = false;
	if (get_uint_param(vp->parsed, "rx_key", &temp_rx)) {
		if (get_uint_param(vp->parsed, "tx_key", &temp_tx)) {
			td->key = true;
			td->expected_header.header |= GRE_MODE_KEY;
			td->rx_key = cpu_to_be32(temp_rx);
			td->tx_key = cpu_to_be32(temp_tx);
			vp->header_size += 4;
			td->sequence_offset += 4;
		} else {
			return -EINVAL;
		}
	}

	td->sequence = false;
	if (get_uint_param(vp->parsed, "sequence", &temp_int)) {
		if (temp_int > 0) {
			vp->header_size += 4;
			td->has_sequence = true;
			td->expected_header.header |= GRE_MODE_SEQUENCE;
			if (get_uint_param(
				vp->parsed, "pin_sequence", &temp_int)) {
				if (temp_int > 0)
					td->pin_sequence = true;
			}
		}
	}
	vp->rx_header_size = vp->header_size;
	if (!td->ipv6)
		vp->rx_header_size += sizeof(struct iphdr);
	return 0;
}