コード例 #1
0
ファイル: tcmsg_filter.c プロジェクト: t2mune/nield
/*
 * parse filter handle
 */
void parse_u32_handle(char *p, int len, unsigned handle)
{
    if(TC_U32_HTID(handle))
        APPEND_SNPRINTF(rc, p, len, "%x", TC_U32_HTID(handle)>>20);

    APPEND_SNPRINTF(rc, p, len, ":");

    if(TC_U32_HASH(handle))
        APPEND_SNPRINTF(rc, p, len, "%x", TC_U32_HASH(handle));

    APPEND_SNPRINTF(rc, p, len, ":");

    if(TC_U32_NODE(handle))
        APPEND_SNPRINTF(rc, p, len, "%x", TC_U32_NODE(handle));
}
コード例 #2
0
ファイル: tcmsg_filter.c プロジェクト: yumkam/nield
/*
 * parse filter handle
 */
void parse_u32_handle(char *p, int len, unsigned handle)
{
    if(TC_U32_HTID(handle))
        p += snprintf(p, len, "%x", TC_U32_HTID(handle)>>20);

    p += snprintf(p, len, ":");

    if(TC_U32_HASH(handle))
        p += snprintf(p, len, "%x", TC_U32_HASH(handle));

    p += snprintf(p, len, ":");

    if(TC_U32_NODE(handle))
        p += snprintf(p, len, "%x", TC_U32_NODE(handle));
}
コード例 #3
0
ファイル: f_u32.c プロジェクト: hvoigt/iproute2
static char * sprint_u32_handle(__u32 handle, char *buf)
{
	int bsize = SPRINT_BSIZE-1;
	__u32 htid = TC_U32_HTID(handle);
	__u32 hash = TC_U32_HASH(handle);
	__u32 nodeid = TC_U32_NODE(handle);
	char *b = buf;

	if (handle == 0) {
		snprintf(b, bsize, "none");
		return b;
	}
	if (htid) {
		int l = snprintf(b, bsize, "%x:", htid>>20);
		bsize -= l;
		b += l;
	}
	if (nodeid|hash) {
		if (hash) {
			int l = snprintf(b, bsize, "%x", hash);
			bsize -= l;
			b += l;
		}
		if (nodeid) {
			int l = snprintf(b, bsize, ":%x", nodeid);
			bsize -= l;
			b += l;
		}
	}
	if (show_raw)
		snprintf(b, bsize, "[%08x] ", handle);
	return buf;
}
コード例 #4
0
static uint32_t get_u32_parse_handle(const char *cHandle)
{
	uint32_t handle=0;

	if(get_u32_handle(&handle, cHandle)) {
		printf ("Illegal \"ht\"\n");
		return -1;
	}

	if (handle && TC_U32_NODE(handle)) {
		printf("\"link\" must be a hash table.\n");
		return -1;
	}
	return handle;
}
コード例 #5
0
int main(void)
{
    struct nl_sock *sock;
    struct rtnl_link *link;
    uint32_t ht, htlink, htid, direction;
    char chashlink[16]="";
    int err;
    struct nl_cache *link_cache;
    struct rtnl_act *act, *act2;
    uint32_t i;

    if (!(sock = nl_socket_alloc())) {
        printf("Unable to allocate netlink socket\n");
        exit(1);
    }

    if ((err = nl_connect(sock, NETLINK_ROUTE)) < 0 ) {
        printf("Nu s-a putut conecta la NETLINK!\n");
        nl_socket_free(sock);
        exit(1);
    }

    if ((err = rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache)) < 0) {
        printf("Unable to allocate link cache: %s\n",
                             nl_geterror(err));
        nl_socket_free(sock);
        exit(1);
    }
    
    /* lookup interface index of eth0 */
    if (!(link = rtnl_link_get_by_name(link_cache, "eth0"))) {
        /* error */
        printf("Interface not found\n");
        nl_socket_free(sock);
        exit(1);
    }
    
    err=qdisc_add_ingress(sock, link);
    //printf("Add main hash table\n");

    /* create u32 first hash filter table
     *
     */
    /* formula calcul handle:
    *         uint32_t handle = (htid << 20) | (hash << 12) | nodeid;
    */

    /*
     * Upper limit of number of hash tables: 4096 (0xFFF)
     * Number of hashes in a table: 256 values (0xFF)
     *
     */

    /* using 256 values for hash table 
     * each entry in hash table match a byte from IP address specified later by a hash key
     */

    for (i = 1; i <= 0xf; i++) 
	u32_add_ht(sock, link, 1, i, 256);

    /* 
     * attach a u32 filter to the first hash 
     * that redirects all traffic and make a hash key
     * from the fist byte of the IP address
     *
     */

    //divisor=0x0;	// unused here
    //handle = 0x0;	// unused here
    //hash = 0x0;		// unused here
    //htid = 0x0;		// unused here
    //nodeid = 0x0;	// unused here

    // direction = 12 -> source IP
    // direction = 16 -> destination IP
    direction = 16;

    /*
     * which hash table will use
     * in our case is hash table no 1 defined previous
     *
     * There are 2 posibilities to set the the hash table:
     * 1. Using function get_u32_handle and sent a string in
     *  format 10: where 10 is number of the hash table
     * 2. Create your own value in format: 0xa00000
     *
     */
    strcpy(chashlink, "1:");
    //printf("Hash Link: %s\n", chashlink);
    //chashlink=malloc(sizeof(char) *
    htlink = 0x0;		// is used by get_u32_handle to return the correct value of hash table (link)
    
    if(get_u32_handle(&htlink, chashlink)) {
        printf ("Illegal \"link\"");
        nl_socket_free(sock);
        exit(1);
    }
    //printf ("hash link : 0x%X\n", htlink);
    //printf ("hash link test : %u\n", (htlink && TC_U32_NODE(htlink)));

    if (htlink && TC_U32_NODE(htlink)) {
	printf("\"link\" must be a hash table.\n");
        nl_socket_free(sock);
        exit(1);
    }

    /* the hash mask will hit the hash table (link) no 1: in our case
     */

    /* set the hash key mask */
    //hashmask = 0xFF000000UL;	// the mask that is used to match the hash in specific table, in our case for example 1:a with mean the first byte which is 10 in hash table 1

    /* Here we add a hash filter which match the first byte (see the hashmask value)
     * of the source IP (offset 12 in the packet header)
     * You can use also offset 16 to match the destination IP
     */

    /*
     * Also we need a filter to match our rule
     * This mean that we will put a 0.0.0.0/0 filter in our first rule
     * that match the offset 12 (source IP)
     * Also you can put offset 16 to match the destination IP
     */

    u32_add_filter_on_ht_with_hashmask(sock, link, 1, 
	    0x0, 0x0, direction, 0,
	    0, htlink, 0xff000000, direction, NULL, NULL);

    /*
     * For each first byte that we need to match we will create a new hash table
     * For example: you have those clases: 10.0.0.0/24 and 172.16.0.0/23
     * For byte 10 and byte 172 will create a separate hash table that will match the second
     * byte from each class.
     *
     */

    
    /*
     * Now we will create other filter under (ATENTION) our first hash table (link) 1:
     * Previous rule redirects the trafic according the hash mask to hash table (link) no 1:
     * Here we will match the hash tables from 1:0 to 1:ff. Under each hash table we will attach 
     * other rules that matches next byte from IP source/destination IP and we will repeat the 
     * previous steps.
     *
     */
    act = rtnl_act_alloc();
    if (!act) {
            printf("rtnl_act_alloc() returns %p\n", act);
            return -1;
    }
    rtnl_tc_set_kind(TC_CAST(act), "skbedit");
    rtnl_skbedit_set_queue_mapping(act, 4);
    rtnl_skbedit_set_action(act, TC_ACT_PIPE);

    act2 = rtnl_act_alloc();
    if (!act2) {
            printf("rtnl_act_alloc() returns %p\n", act2);
            return -1;
    }
    rtnl_tc_set_kind(TC_CAST(act2), "mirred");
    rtnl_mirred_set_action(act2, TCA_EGRESS_REDIR);
    rtnl_mirred_set_policy(act2, TC_ACT_STOLEN);
    rtnl_mirred_set_ifindex(act2, rtnl_link_name2i(link_cache, "eth1"));
    // /8 check

    // 10.0.0.0/8
    ht=get_u32_parse_handle("1:a:");
    htid = (ht&0xFFFFF000);
    htlink=get_u32_parse_handle("2:");

    u32_add_filter_on_ht_with_hashmask(sock, link, 1, 
	    0x0a000000, 0xff000000, direction, 0,
	    htid, htlink, 0x00ff0000, direction, act, act2);

    rtnl_act_put(act);
    nl_socket_free(sock);
    return 0;
}
コード例 #6
0
ファイル: f_u32.c プロジェクト: zipangotes/DSL-G624T_GPL_code
static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	struct {
		struct tc_u32_sel sel;
		struct tc_u32_key keys[128];
	} sel;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	int sel_ok = 0;
	int sample_ok = 0;
	__u32 htid = 0;
	__u32 order = 0;

	memset(&sel, 0, sizeof(sel));

	if (handle && get_u32_handle(&t->tcm_handle, handle)) {
		fprintf(stderr, "Illegal filter ID\n");
		return -1;
	}

	if (argc == 0)
		return 0;

	tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len));
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"match\"\n");
				return -1;
			}
			sel_ok++;
			continue;
		} else if (matches(*argv, "offset") == 0) {
			NEXT_ARG();
			if (parse_offset(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"offset\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "hashkey") == 0) {
			NEXT_ARG();
			if (parse_hashkey(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"hashkey\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "classid") == 0 ||
			   strcmp(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_U32_CLASSID, &handle, 4);
			sel.sel.flags |= TC_U32_TERMINAL;
		} else if (matches(*argv, "divisor") == 0) {
			unsigned divisor;
			NEXT_ARG();
			if (get_unsigned(&divisor, *argv, 0) || divisor == 0 ||
			    divisor > 0x100) {
				fprintf(stderr, "Illegal \"divisor\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_U32_DIVISOR, &divisor, 4);
		} else if (matches(*argv, "order") == 0) {
			NEXT_ARG();
			if (get_u32(&order, *argv, 0)) {
				fprintf(stderr, "Illegal \"order\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "link") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"link\"\n");
				return -1;
			}
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"link\" must be a hash table.\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_U32_LINK, &handle, 4);
		} else if (strcmp(*argv, "ht") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"ht\"\n");
				return -1;
			}
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"ht\" must be a hash table.\n");
				return -1;
			}
			if (sample_ok)
				htid = (htid&0xFF000)|(handle&0xFFF00000);
			else
				htid = (handle&0xFFFFF000);
		} else if (strcmp(*argv, "sample") == 0) {
			__u32 hash;
			struct {
				struct tc_u32_sel sel;
				struct tc_u32_key keys[4];
			} sel2;
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel2.sel)) {
				fprintf(stderr, "Illegal \"sample\"\n");
				return -1;
			}
			if (sel2.sel.nkeys != 1) {
				fprintf(stderr, "\"sample\" must contain exactly ONE key.\n");
				return -1;
			}
			hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask;
			hash ^= hash>>16;
			hash ^= hash>>8;
			htid = ((hash<<12)&0xFF000)|(htid&0xFFF00000);
			sample_ok = 1;
			continue;
#ifdef TC_CONFIG_ALL
		} else if (matches(*argv, "police") == 0) {
コード例 #7
0
static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	struct {
		struct tc_u32_sel sel;
		struct tc_u32_key keys[128];
	} sel;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	int sel_ok = 0;
	int sample_ok = 0;
	__u32 htid = 0;
	__u32 order = 0;

	memset(&sel, 0, sizeof(sel));

//fprintf(stderr, "handle[%s]\n", handle);

	if (handle && get_u32_handle(&t->tcm_handle, handle)) {
		fprintf(stderr, "Illegal filter ID\n");
		return -1;
	}

	if (argc == 0)
		return 0;



	tail = NLMSG_TAIL(n);
	addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel.sel, n)) {
				fprintf(stderr, "Illegal \"match\"\n");
				return -1;
			}
			sel_ok++;
			continue;
		} else if (matches(*argv, "offset") == 0) {
			NEXT_ARG();
			if (parse_offset(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"offset\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "hashkey") == 0) {
			NEXT_ARG();
			if (parse_hashkey(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"hashkey\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "classid") == 0 ||
			   strcmp(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, MAX_MSG, TCA_U32_CLASSID, &handle, 4);
			sel.sel.flags |= TC_U32_TERMINAL;
		} else if (matches(*argv, "divisor") == 0) {
			unsigned int divisor;
fprintf(stderr, "parse divisor\n");
			NEXT_ARG();
			if (get_unsigned(&divisor, *argv, 0) || 
			    divisor == 0 ||
			   //divisor > 0x100 || ((divisor - 1) & divisor)) {//richie1124
			   divisor > 0x1000 || ((divisor - 1) & divisor)) {
				fprintf(stderr, "Illegal \"divisor\"\n");
				return -1;
			}
			addattr_l(n, MAX_MSG, TCA_U32_DIVISOR, &divisor, 4);
		} else if (matches(*argv, "order") == 0) {
			NEXT_ARG();
			if (get_u32(&order, *argv, 0)) {
				fprintf(stderr, "Illegal \"order\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "link") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"link\"\n");
				return -1;
			}
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"link\" must be a hash table.\n");
				return -1;
			}
			addattr_l(n, MAX_MSG, TCA_U32_LINK, &handle, 4);
		} else if (strcmp(*argv, "ht") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"ht\"\n");
				return -1;
			}
//fprintf(stderr, "f_u32, handle[%x]\n", handle);
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"ht\" must be a hash table.\n");
				return -1;
			}
			if (sample_ok)
			{
				//htid = (htid&0xFF000)|(handle&0xFFF00000);
				//htid = (htid&0xFFF00)|(handle&0xFFF00000);
				htid = (htid&0xFFF00)|(handle&0xFFF00000);//richie1124
			}
			else
			{
				//htid = (handle&0xFFFFF000);
				htid = (handle&0xFFFFFF00);
				//htid = (handle&0xFFFFFF00);//richie1124
			}
		} else if (strcmp(*argv, "sample") == 0) {
			__u32 hash;
			unsigned divisor = 0x100;

			struct {
				struct tc_u32_sel sel;
				struct tc_u32_key keys[4];
			} sel2;
			memset(&sel2, 0, sizeof(sel2));
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel2.sel, n)) {
				fprintf(stderr, "Illegal \"sample\"\n");
				return -1;
			}
			if (sel2.sel.nkeys != 1) {
				fprintf(stderr, "\"sample\" must contain exactly ONE key.\n");
				return -1;
			}
			if (*argv != 0 && strcmp(*argv, "divisor") == 0) {
				NEXT_ARG();
				if (get_unsigned(&divisor, *argv, 0) || divisor == 0 ||
				    divisor > 0x100 || ((divisor - 1) & divisor)) {
					fprintf(stderr, "Illegal sample \"divisor\"\n");
					return -1;
				}
				NEXT_ARG();
			}
			hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask;
			hash ^= hash>>16;
			hash ^= hash>>8;
			htid = ((hash%divisor)<<12)|(htid&0xFFF00000);
			sample_ok = 1;
			continue;
		} else if (strcmp(*argv, "indev") == 0) {