int GetLWSessionKey(Packet *p, SessionKey *key)
{
    u_int16_t sport;
    u_int16_t dport;
    int proto;
    /* Because the key is going to be used for hash lookups,
     * the lower of the values of the IP address field is
     * stored in the key->ip_l and the port for that ip is
     * stored in key->port_l.
     */

    if (!key)
        return 0;

#ifdef SUP_IP6
    if (IS_IP4(p))
    {
        u_int32_t *src;
        u_int32_t *dst;

        proto = p->iph->ip_proto;

        switch (proto)
        {
        case IPPROTO_TCP:
        case IPPROTO_UDP:
            sport = p->sp;
            dport = p->dp;
            break;
        case IPPROTO_ICMP:
        default:
            sport = dport = 0;
            break;
        }

        src = p->ip4h.ip_src.ip32;
        dst = p->ip4h.ip_dst.ip32;

        /* These comparisons are done in this fashion for performance reasons */
        if (*src < *dst)
        {
            COPY4(key->ip_l, src);
            COPY4(key->ip_h, dst);
            key->port_l = sport;
            key->port_h = dport;
        }
        else if (*src == *dst)
        {
            COPY4(key->ip_l, src);
            COPY4(key->ip_h, dst);
            if (sport < dport)
            {
                key->port_l = sport;
                key->port_h = dport;
            }
            else
            {
                key->port_l = dport;
                key->port_h = sport;
            }
        }
        else
        {
            COPY4(key->ip_l, dst);
            key->port_l = dport;
            COPY4(key->ip_h, src);
            key->port_h = sport;
        }
#ifdef MPLS
        if(pv.overlapping_IP && (p->mpls)
                && isPrivateIP(*src) && isPrivateIP(*dst) )
        {
            key->mplsLabel = p->mplsHdr.label;
        } else {
            key->mplsLabel = 0;
        }
#endif
    }
    else
    {
        /* IPv6 */
        sfip_t *src;
        sfip_t *dst;

        proto = p->ip6h.next;

        switch (proto)
        {
        case IPPROTO_TCP:
        case IPPROTO_UDP:
            sport = p->sp;
            dport = p->dp;
            break;
        case IPPROTO_ICMP:
        default:
            sport = dport = 0;
            break;
        }

        src = &p->ip6h.ip_src;
        dst = &p->ip6h.ip_dst;

        if (sfip_fast_lt6(src, dst))
        {
            COPY4(key->ip_l, src->ip32);
            key->port_l = sport;
            COPY4(key->ip_h, dst->ip32);
            key->port_h = dport;
        }
        else if (sfip_fast_eq6(src, dst))
        {
            COPY4(key->ip_l, src->ip32);
            COPY4(key->ip_h, dst->ip32);
            if (sport < dport)
            {
                key->port_l = sport;
                key->port_h = dport;
            }
            else
            {
                key->port_l = dport;
                key->port_h = sport;
            }
        }
        else
        {
            COPY4(key->ip_l, dst->ip32);
            key->port_l = dport;
            COPY4(key->ip_h, src->ip32);
            key->port_h = sport;
        }
#ifdef MPLS
        if(pv.overlapping_IP && (p->mpls))
        {
            key->mplsLabel = p->mplsHdr.label;
        } else {
            key->mplsLabel = 0;
        }
#endif
    }
#else
    proto = p->iph->ip_proto;

    switch (proto)
    {
    case IPPROTO_TCP:
    case IPPROTO_UDP:
        sport = p->sp;
        dport = p->dp;
        break;
    case IPPROTO_ICMP:
    default:
        sport = dport = 0;
        break;
    }

    /* These comparisons are done in this fashion for performance reasons */
    if (IP_LESSER(GET_SRC_IP(p), GET_DST_IP(p)))
    {
        IP_COPY_VALUE(key->ip_l, GET_SRC_IP(p));
        key->port_l = sport;
        IP_COPY_VALUE(key->ip_h, GET_DST_IP(p));
        key->port_h = dport;
    }
    else if (IP_EQUALITY(GET_SRC_IP(p), GET_DST_IP(p)))
    {
        IP_COPY_VALUE(key->ip_l, GET_SRC_IP(p));
        IP_COPY_VALUE(key->ip_h, GET_DST_IP(p));
        if (sport < dport)
        {
            key->port_l = sport;
            key->port_h = dport;
        }
        else
        {
            key->port_l = dport;
            key->port_h = sport;
        }
    }
    else
    {
        IP_COPY_VALUE(key->ip_l, GET_DST_IP(p));
        key->port_l = dport;
        IP_COPY_VALUE(key->ip_h, GET_SRC_IP(p));
        key->port_h = sport;
    }
#ifdef MPLS
    if(pv.overlapping_IP && (p->mpls)
            && isPrivateIP(key->ip_l) && isPrivateIP(key->ip_h))
    {
        key->mplsLabel = p->mplsHdr.label;
    } else {
        key->mplsLabel = 0;
    }
#endif
#endif

    key->protocol = proto;

    if (p->vh)
        key->vlan_tag = (u_int16_t)VTH_VLAN(p->vh);
    else
        key->vlan_tag = 0;

    key->pad = 0;
#ifdef MPLS
    key->mplsPad = 0;
#endif
    return 1;
}
Example #2
0
/* Set the fragment, texenv (constant), and texture colors for all the
 * machine's texture units. */
static void
setup_colors(void)
{
	static const float frag_color[4] = {0.00, 0.25, 0.50, 0.75};
	static const float env_colors[][4] = {{0.25, 0.50, 0.75, 1.00},
					      {0.50, 0.75, 1.00, 0.00},
					      {0.75, 1.00, 0.00, 0.25},
					      {1.00, 0.00, 0.25, 0.50}};
	static const float tex_colors[][8] = {
		{1.00, 0.00, 0.25, 0.50},
		{0.75, 1.00, 0.00, 0.25},
		{0.50, 0.75, 1.00, 0.00},
		{0.25, 0.50, 0.75, 1.00},
		/* extra colors that'll only be used for crossbar test */
		{0.00, 0.00, 0.00, 0.00},
		{0.25, 0.50, 0.50, 0.00},
		{0.50, 0.25, 0.75, 0.25},
		{0.75, 1.00, 0.25, 0.00}};

	COPY4(machine.frag_color, frag_color);
	glColor4fv(frag_color);

	for (int u = 0; u < num_tex_units; u++) {
		if (num_tex_units > 1)
			glActiveTexture(GL_TEXTURE0 + u);
		glBindTexture(GL_TEXTURE_2D, textures[u]);
		glEnable(GL_TEXTURE_2D);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
				GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
				GL_NEAREST);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
			  GL_COMBINE_EXT);
		machine.env_color[u][0] = env_colors[u % 4][0];
		machine.env_color[u][1] = env_colors[u % 4][1];
		machine.env_color[u][2] = env_colors[u % 4][2];
		machine.env_color[u][3] = env_colors[u % 4][3];
		glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
			   env_colors[u % 4]);

		const float *tex_col = tex_colors[u % 8];

		/* Setup texture color, according to texture format */
		switch (machine.tex_format[u]) {
		case GL_RGBA:
			machine.tex_color[u][0] = tex_col[0];
			machine.tex_color[u][1] = tex_col[1];
			machine.tex_color[u][2] = tex_col[2];
			machine.tex_color[u][3] = tex_col[3];
			break;
		case GL_RGB:
			machine.tex_color[u][0] = tex_col[0];
			machine.tex_color[u][1] = tex_col[1];
			machine.tex_color[u][2] = tex_col[2];
			machine.tex_color[u][3] = 1.0;
			break;
		case GL_ALPHA:
			machine.tex_color[u][0] = 0.0;
			machine.tex_color[u][1] = 0.0;
			machine.tex_color[u][2] = 0.0;
			machine.tex_color[u][3] = tex_col[3];
			break;
		case GL_LUMINANCE:
			machine.tex_color[u][0] = tex_col[0];
			machine.tex_color[u][1] = tex_col[0];
			machine.tex_color[u][2] = tex_col[0];
			machine.tex_color[u][3] = 1.0;
			break;
		case GL_LUMINANCE_ALPHA:
			machine.tex_color[u][0] = tex_col[0];
			machine.tex_color[u][1] = tex_col[0];
			machine.tex_color[u][2] = tex_col[0];
			machine.tex_color[u][3] = tex_col[3];
			break;
		case GL_INTENSITY:
			machine.tex_color[u][0] = tex_col[0];
			machine.tex_color[u][1] = tex_col[0];
			machine.tex_color[u][2] = tex_col[0];
			machine.tex_color[u][3] = tex_col[0];
			break;
		default:
			problem("bad texture format");
			return;
		}

		/* Make a 4x4 solid color texture */
		float image[16][4];
		for (int i = 0; i < 16; i++) {
			image[i][0] = tex_colors[u % 8][0];
			image[i][1] = tex_colors[u % 8][1];
			image[i][2] = tex_colors[u % 8][2];
			image[i][3] = tex_colors[u % 8][3];
		}
		glTexImage2D(GL_TEXTURE_2D, 0, machine.tex_format[u], 4, 4, 0,
			     GL_RGBA, GL_FLOAT, image);
	}
}
Example #3
0
/* Test texenv-combine with multiple texture units. */
static bool
run_multi_texture_test(void)
{
	static const GLenum combine_modes[10] = {
		GL_REPLACE,
		GL_ADD,
		GL_ADD_SIGNED_EXT,
		GL_MODULATE,
		GL_INTERPOLATE_EXT,
		GL_DOT3_RGB_EXT,
		GL_DOT3_RGBA_EXT,
		GL_MODULATE_ADD_ATI,
		GL_MODULATE_SIGNED_ADD_ATI,
		GL_MODULATE_SUBTRACT_ATI
	};
	const int num_modes = have_dot3 ? (have_combine3 ? 10 : 7) : 5;

	/* four texture units is enough to test */
	if (num_tex_units > 4)
		num_tex_units = 4;

	const int num_tests = count_multi_texture_test_combinations();

	setup_colors();
	for (int test_num = 0; test_num < num_tests;
	     test_num += test_stride) {
		/* 0. Set up texture units */
		reset_machine();
		int divisor = 1;
		for (int u = 0; u < num_tex_units; u++) {
			const int m = (test_num / divisor) % num_modes;
			const GLenum mode = combine_modes[m];

			/* Set GL_COMBINE_RGB_EXT and GL_COMBINE_ALPHA_EXT */
			tex_env(u, GL_COMBINE_RGB_EXT, mode);
			tex_env(u, GL_COMBINE_ALPHA_EXT,
				(mode == GL_DOT3_RGB_EXT ||
				 mode == GL_DOT3_RGBA_EXT)
					? GL_REPLACE
					: mode);
			tex_env(u, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
			tex_env(u, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
			tex_env(u, GL_SOURCE2_RGB_EXT, GL_TEXTURE);
			tex_env(u, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
			tex_env(u, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT);
			tex_env(u, GL_SOURCE2_ALPHA_EXT, GL_TEXTURE);
			tex_env(u, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
			tex_env(u, GL_OPERAND1_RGB_EXT,
				GL_ONE_MINUS_SRC_COLOR);
			tex_env(u, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
			tex_env(u, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
			tex_env(u, GL_OPERAND1_ALPHA_EXT,
				GL_ONE_MINUS_SRC_ALPHA);
			tex_env(u, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
			tex_env(u, GL_RGB_SCALE_EXT, 1);
			tex_env(u, GL_ALPHA_SCALE, 1);

			divisor *= num_modes;
		}

		/* 1. Render with OpenGL */
		/* use texcoord (0,0) for all vertices */
		for (int u = 0; u < num_tex_units; u++)
			glMultiTexCoord2f(GL_TEXTURE0 + u, 0, 0);
		piglit_draw_rect(-1, -1, 2, 2);

		/* 2. Compute expected result */
		float prev_color[4];
		float expected[4] = {0};
		COPY4(prev_color, machine.frag_color);
		for (int u = 0; u < num_tex_units; u++) {
			compute_tex_combine(u, prev_color, expected);
			COPY4(prev_color, expected);
		}

		/* 3. Compare rendered result to expected result */
		if (!piglit_probe_pixel_rgba(0, 0, expected)) {
			printf("Multi-texture test %d\n", test_num);
			return false;
		}
	}
	return true;
}
Example #4
0
/* We do a really short, simple test for GL_ARB_texture_env_crossbar since the
 * preceeding tests are pretty comprehensive and the crossbar feature is just
 * an incremental addition.  Basically, if we have N texture units we run N
 * tests.  For test [i] we set texture unit [i] to fetch the texture color
 * from unit [num_units - i - 1].  For units != i we use the constant color
 * (0,0,0,0).  We use GL_ADD mode to compute the sum over all units.  So
 * effectively, the result of texture combine is simply the incoming fragment
 * color plus unit [num_units - test - 1]'s texture color. */
static bool
run_crossbar_test()
{
	glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num_tex_units);

	/* Set up constant texture state for all tests */
	setup_colors();
	reset_machine();
	for (int unit = 0; unit < num_tex_units; unit++) {
		tex_env(unit, GL_COMBINE_RGB_EXT, GL_ADD);
		tex_env(unit, GL_COMBINE_ALPHA_EXT, GL_ADD);
		tex_env(unit, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
		tex_env(unit, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
		/* SOURCE1_RGB/ALPHA is set below, per test */
		tex_env(unit, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
		tex_env(unit, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
		tex_env(unit, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
		tex_env(unit, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
		tex_env(unit, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
		tex_env(unit, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
		tex_env(unit, GL_RGB_SCALE_EXT, 1);
		tex_env(unit, GL_ALPHA_SCALE, 1);

		machine.env_color[unit][0] = 0.0;
		machine.env_color[unit][1] = 0.0;
		machine.env_color[unit][2] = 0.0;
		machine.env_color[unit][3] = 0.0;
		glActiveTexture(GL_TEXTURE0 + unit);
		glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
			   machine.env_color[unit]);
	}

	for (int test = 0; test < num_tex_units; test++) {
		/* 1. Set up texture state */
		for (int unit = 0; unit < num_tex_units; unit++) {
			if (unit == test) {
				const int revUnit = num_tex_units - unit - 1;
				tex_env(unit, GL_SOURCE1_RGB_EXT,
					GL_TEXTURE0 + revUnit);
				tex_env(unit, GL_SOURCE1_ALPHA_EXT,
					GL_TEXTURE0 + revUnit);
			} else {
				tex_env(unit, GL_SOURCE1_RGB_EXT,
					GL_CONSTANT_EXT);
				tex_env(unit, GL_SOURCE1_ALPHA_EXT,
					GL_CONSTANT_EXT);
			}
		}

		/* 2. Render with OpenGL */
		/* texcoord (0,) for all vertices is OK */
		for (int unit = 0; unit < num_tex_units; unit++)
			glMultiTexCoord2f(GL_TEXTURE0 + unit, 0, 0);
		piglit_draw_rect(-1, -1, 2, 2);

		/* 3. Compute expected result */
		float prev_color[4];
		float expected[4];
		COPY4(prev_color, machine.frag_color);
		for (int unit = 0; unit < num_tex_units; unit++) {
			compute_tex_combine(unit, prev_color, expected);
			COPY4(prev_color, expected);
		}

		/* 4. Compare rendered result to expected result */
		if (!piglit_probe_pixel_rgba(0, 0, expected)) {
			printf("Texture crossbar test %d\n", test);
			return false;
		}
	}
	return true;
}
Example #5
0
static int ProcessIcmpUnreach(Packet *p)
{
    /* Handle ICMP unreachable */
    SessionKey skey;
    SessionControlBlock *ssn = NULL;
    uint16_t sport;
    uint16_t dport;
    sfip_t *src;
    sfip_t *dst;

    /* No "orig" IP Header */
    if (!p->orig_iph)
        return 0;

    /* Get TCP/UDP/ICMP session from original protocol/port info
     * embedded in the ICMP Unreach message.  This is already decoded
     * in p->orig_foo.  TCP/UDP ports are decoded as p->orig_sp/dp.
     */
    skey.protocol = GET_ORIG_IPH_PROTO(p);
    sport = p->orig_sp;
    dport = p->orig_dp;

    src = GET_ORIG_SRC(p);
    dst = GET_ORIG_DST(p);

    if (sfip_fast_lt6(src, dst))
    {
        COPY4(skey.ip_l, src->ip32);
        skey.port_l = sport;
        COPY4(skey.ip_h, dst->ip32);
        skey.port_h = dport;
    }
    else if (IP_EQUALITY(GET_ORIG_SRC(p), GET_ORIG_DST(p)))
    {
        COPY4(skey.ip_l, src->ip32);
        COPY4(skey.ip_h, skey.ip_l);
        if (sport < dport)
        {
            skey.port_l = sport;
            skey.port_h = dport;
        }
        else
        {
            skey.port_l = dport;
            skey.port_h = sport;
        }
    }
    else
    {
        COPY4(skey.ip_l, dst->ip32);
        COPY4(skey.ip_h, src->ip32);
        skey.port_l = dport;
        skey.port_h = sport;
    }

    if (p->vh)
        skey.vlan_tag = (uint16_t)VTH_VLAN(p->vh);
    else
        skey.vlan_tag = 0;

    switch (skey.protocol)
    {
    case IPPROTO_TCP:
        /* Lookup a TCP session */
        ssn = GetLWTcpSession(&skey);
        break;
    case IPPROTO_UDP:
        /* Lookup a UDP session */
        ssn = GetLWUdpSession(&skey);
        break;
    case IPPROTO_ICMP:
        /* Lookup a ICMP session */
        ssn = session_api->get_session_by_key(icmp_lws_cache, &skey);
        break;
    }

    if (ssn)
    {
        /* Mark this session as dead. */
        DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
            "Marking session as dead, per ICMP Unreachable!\n"););
        ssn->ha_state.session_flags |= SSNFLAG_DROP_CLIENT;
        ssn->ha_state.session_flags |= SSNFLAG_DROP_SERVER;
        ssn->session_state |= STREAM_STATE_UNREACH;
    }