예제 #1
0
HYFI_MC_STATIC unsigned int mc_pre_routing_hook(unsigned int hooknum, struct sk_buff *skb,
        const struct net_device *in, const struct net_device *out,
        int(*okfn)(struct sk_buff *))
{ 
	struct hyfi_net_bridge *hyfi_br = hyfi_bridge_get_by_dev(in);
    struct mc_struct *mc = MC_DEV(hyfi_br);
    struct ethhdr *eh = eth_hdr(skb);
    struct net_bridge_port *port;
    u8 dscp;

    if (!mc || skb->pkt_type != PACKET_HOST ||
            (port = hyfi_br_port_get(in)) == NULL)
        goto out;

    dscp = MC_DSCP(mc->dscp) & (~INET_ECN_MASK);

    switch (ntohs(skb->protocol)) {
        case ETH_P_IP:
            {
                const struct iphdr *iph = ip_hdr(skb);
                if (ipv4_is_multicast(iph->daddr) && (!mc->enable_retag || 
                            (mc->enable_retag && (ipv4_get_dsfield(iph) == dscp)))) {
                    ip_eth_mc_map(iph->daddr, eh->h_dest);

                    if (mc->debug && printk_ratelimit()) {
                        MC_PRINT("Decap the group "MC_IP4_STR" back to "MC_MAC_STR"\n", 
                                 MC_IP4_FMT((u8 *)(&iph->daddr)) ,MC_MAC_FMT(eh->h_dest));
                    }
                    skb->pkt_type = PACKET_MULTICAST;
                }
            }
            break;
#ifdef HYBRID_MC_MLD
        case ETH_P_IPV6:
            {
                struct ipv6hdr *iph6 = ipv6_hdr(skb);
                if (ipv6_addr_is_multicast(&iph6->daddr) && (!mc->enable_retag || 
                            (mc->enable_retag && (ipv6_get_dsfield(iph6) == dscp)))) {
                    ipv6_eth_mc_map(&iph6->daddr, eh->h_dest);

                    if (mc->debug && printk_ratelimit()) {
                        MC_PRINT("Decap the group "MC_IP6_STR" back to "MC_MAC_STR"\n", 
                                 MC_IP6_FMT((__be16 *)(&iph6->daddr)) ,MC_MAC_FMT(eh->h_dest));
                    }
                    skb->pkt_type = PACKET_MULTICAST;
                }
            }
            break;
#endif
    }
out:
    return NF_ACCEPT;
}
예제 #2
0
파일: rfc.c 프로젝트: c-ber/cber
int  rfc_phase(rfc_pnoder_s *pst_node1, rfc_pnoder_s *pst_node2, rfc_pnoder_s *pst_node3, uint32_t ul_table)
{
    uint32_t i, j, m;
    uint32_t ul_cell_num, ul_eq_id, ul_cell_index;
    uint64_t ud_bmp[RFC_SIZE64], *pud_bmp1, *pud_bmp2;
    rfc_ces_s *pst_ces1, *pst_ces2;
    rfc_phase_set_s *pst_acl_commit = g_ix_rfc_table_base->pst_acl_commit;
    rfc_phase_data_s *pst_acl_phase_data = &g_ix_rfc_table_base->st_acl_phase_data;

    ul_cell_num = pst_node1->ul_eq_id * pst_node2->ul_eq_id;
    
    // Initialize phase0_Nodes[com]->listEqs
    if (rfc_noder_init(pst_acl_commit, pst_acl_phase_data, pst_node3, ul_cell_num) != ACL_OK)
    {
        MC_PRINT("  cell alloc failure in table %d, need is %d, free is %d\n", ul_table, ul_cell_num, pst_acl_commit->ul_free_cell_num);
        return ACL_CELL_ERROR;
    }
    
    // generate phase1_Nodes[com]->listEqs
    pst_ces1 = &pst_acl_phase_data->st_ces[pst_node1->ul_ces_index];
    pst_ces2 = &pst_acl_phase_data->st_ces[pst_node2->ul_ces_index];
    ul_cell_index = 0;
    
    for (i = 0; i < pst_node1->ul_eq_id; i++)
    {
        pud_bmp1 = &pst_acl_phase_data->ud_cbm_data[pst_ces1[i].ul_cbm_index];
        
        for (j = 0; j < pst_node2->ul_eq_id; j++)
        {
            pud_bmp2 = &pst_acl_phase_data->ud_cbm_data[pst_ces2[j].ul_cbm_index];
            
            for (m = 0; m < pst_acl_phase_data->u_real_size; m++)
                ud_bmp[m] = pud_bmp1[m] & pud_bmp2[m];
                
            if ((ul_eq_id = rfc_search_bmp(ud_bmp, ul_table)) == ACL_END_LINK)
            {
                MC_PRINT("  EQM ID search failure in table %d\n", ul_table);
                return ACL_CES_ERROR;
            }
            
            MPP_GET_MDU_VAR(pst_node3->pul_cell) [ul_cell_index++] = ul_eq_id;
        }
    }
    
    return ACL_OK;
}
예제 #3
0
파일: rfc.c 프로젝트: c-ber/cber
// Function to fill the table of Phase 2, called by main
// return : void
int rfc_phase3(rfc_pnoder_s *pst_prev_phase_nodes, rfc_pnoder_s *pst_phase_nodes, uint16_t u_ifgroup)
{
    rfc_pnoder_s *pst_node1, *pst_node2;
    uint64_t ud_bmp[RFC_SIZE64], *pud_bmp1, *pud_bmp2;
    uint32_t ul_cell_num, ul_cell_index;
    uint32_t ul_cost;                               // cost number with highest priority
    rfc_ces_s *pst_ces1, *pst_ces2;
    rfc_phase_set_s *pst_acl_commit = g_ix_rfc_table_base->pst_acl_commit;
    rfc_phase_data_s *pst_acl_phase_data = &g_ix_rfc_table_base->st_acl_phase_data;
    rule_comit_t *pst_filter_index = &g_ix_rfc_table_base->commit;
    uint32_t i, j, m;
    pst_node1 = &pst_prev_phase_nodes[0];
    pst_node2 = &pst_prev_phase_nodes[1];

    // alloc memory for Phase2 cell
    ul_cell_num = pst_node1->ul_eq_id * pst_node2->ul_eq_id;
    
    // Initialize phase0_Nodes[com]->listEqs
    if (rfc_noder_init(pst_acl_commit, pst_acl_phase_data, pst_phase_nodes, ul_cell_num) != ACL_OK)
    {
        MC_PRINT("  cell alloc failure in table %u, need is %u, free is %u\n", 12, ul_cell_num, pst_acl_commit->ul_free_cell_num);
        return ACL_CELL_ERROR;
    }
    
    // generate phase1_Nodes[com]->listEqs
    pst_ces1 = &pst_acl_phase_data->st_ces[pst_node1->ul_ces_index];
    pst_ces2 = &pst_acl_phase_data->st_ces[pst_node2->ul_ces_index];
    ul_cell_index = 0;
    
    for (i = 0; i < pst_node1->ul_eq_id; i++)
    {
        pud_bmp1 = &pst_acl_phase_data->ud_cbm_data[pst_ces1[i].ul_cbm_index];
        
        for (j = 0; j < pst_node2->ul_eq_id; j++)
        {
            pud_bmp2 = &pst_acl_phase_data->ud_cbm_data[pst_ces2[j].ul_cbm_index];
            
            for (m = 0; m < pst_acl_phase_data->u_real_size; m++)
                ud_bmp[m] = pud_bmp1[m] & pud_bmp2[m];
                
            ul_cost = rfc_get_rule_cost(ud_bmp);
            
            if (ul_cost == CHUNK_TOTAL_SZIE)
                pst_phase_nodes->pul_cell_mdu[ul_cell_index++] = CHUNK_TOTAL_SZIE;
                
            else
                pst_phase_nodes->pul_cell_mdu[ul_cell_index++] = pst_filter_index[u_ifgroup].rule_status[ul_cost];
        }
    }
    
    return ACL_OK;
}
예제 #4
0
파일: rfc.c 프로젝트: c-ber/cber
// Function to fill the table of Phase 0
// return : void
int rfc_phase0(rfc_phase_set_s *pst_acl_commit, rule_set_t *pst_filter_set, rule_comit_t *pst_filter_index)
{
    uint32_t i     = 0;
    uint32_t n     = 0;
    uint32_t com   = 0;
    uint32_t index = 0;//存放当前chunk中的有效的索引值
    uint64_t ud_bmp[RFC_SIZE64];
    uint32_t ul_action_num, ul_eq_id;

    rule_action_t *pst_filter_action[MPP_MAX_PHASE0_CELL] = {NULL};
    rule_action_t *pst_action_temp                        = NULL;

    rule_action_t  st_filter_action[2 * CHUNK_TOTAL_SZIE] = {};

    rfc_phase_data_s *pst_acl_phase_data = &g_ix_rfc_table_base->st_acl_phase_data;
    
    // Chunk[0] to Chunk[5] of Phase 0
    for (com = 0; com < CHUNK_TOTAL_SZIE; com++)
    {
        printf("sizeof(pst_filter_action) = %d \n", sizeof(pst_filter_action));
        memset (pst_filter_action, 0, sizeof(pst_filter_action));
        memset (st_filter_action, 0, sizeof(st_filter_action));
        
        // Initialize ud_bmp = 0
        for (i = 0; i < pst_acl_phase_data->u_real_size; i++)
            ud_bmp[i] = 0;
            
        ul_action_num = 0;
        ul_eq_id      = 0;
        
        // Initialize phase0_Nodes[com]->listEqs
        if (rfc_noder_init(pst_acl_commit, pst_acl_phase_data, pst_acl_commit->st_phase_nodes + com, MPP_MAX_PHASE0_CELL) != ACL_OK)
        {
            MC_PRINT("  cell alloc failure in table %d, need is %d, free is %d\n", com, MPP_MAX_PHASE0_CELL, pst_acl_commit->ul_free_cell_num);
            //          Phase_Free();
            return ACL_CELL_ERROR;
        }
        
        // Pre scan for action
        //13个chunk都有各自的一个ces表,里面cbm是用链表串起来的长度,单个是64位
        for (n = 0; n < pst_filter_index->rule_num; n++)
        {
            st_filter_action[ul_action_num].rid = n / LENGTH64;
            st_filter_action[ul_action_num].action = 1;

            /**/
            DATA64_BITMASK_SET (&st_filter_action[ul_action_num].bitmask, n);
            index = pst_filter_set->rule[pst_filter_index->rule_status[n]].rule_item[com][0];
            st_filter_action[ul_action_num].ck_index = index;
            st_filter_action[ul_action_num].next = pst_filter_action[index];

            /*这里赋值了,就说明这个chunk项的index项不为空*/
            pst_filter_action[index] = &st_filter_action[ul_action_num];
            ul_action_num++;
            // second is high+1, the clear bit
            index = pst_filter_set->rule[pst_filter_index->rule_status[n]].rule_item[com][1] + 1;
            
            if (index <= MPP_MAX_PHASE0_CELL)
            {
                st_filter_action[ul_action_num].rid = n / LENGTH64;
                st_filter_action[ul_action_num].action = 0;
                //st_filter_action[ul_action_num].ud_bitmask = 1 << (n & (LENGTH64 - 1));
                DATA64_BITMASK_SET (&st_filter_action[ul_action_num].bitmask, n);
                st_filter_action[ul_action_num].next = pst_filter_action[index];
                st_filter_action[ul_action_num].ck_index = index;

                pst_filter_action[index] = &st_filter_action[ul_action_num];
                ul_action_num++;
            }
        }
        
        //  first the cbm is 0
        if (pst_filter_action[0] == NULL)
        {
            if ((ul_eq_id = rfc_search_bmp(ud_bmp, com)) == ACL_END_LINK)
            {
                MC_PRINT("  EQM ID search failure in table %d\n", com);
                //Phase_Free();
                return ACL_CES_ERROR;
            }
        }
        //预处理表赋值,action为空时候, eq_id为0, 否则填对应的值
        for (i = 0; i < MPP_MAX_PHASE0_CELL; i++)
        {
            if (pst_filter_action[i] != NULL)
            {
                pst_action_temp = pst_filter_action[i];
                
                while (pst_action_temp != NULL)
                {
                    if (pst_action_temp->action)
                        ud_bmp[pst_action_temp->rid] |= pst_action_temp->bitmask;
                        
                    else
                        ud_bmp[pst_action_temp->rid] &= ~pst_action_temp->bitmask;
                        
                    pst_action_temp = pst_action_temp->next;
                }
                
                if ((ul_eq_id = rfc_search_bmp(ud_bmp, com)) == ACL_END_LINK)
                {
                    MC_PRINT("  EQM ID search failure in table %d\n", com);
                    return ACL_CES_ERROR;
                }
            }

            pst_acl_commit->st_phase_nodes[com].pul_cell_mdu[i] = ul_eq_id;
        }
        
        for (i = 0; i < ul_action_num; i++)
            pst_filter_action[st_filter_action[i].ck_index] = NULL;
    }
    
    return ACL_OK;
}
예제 #5
0
파일: rfc.c 프로젝트: c-ber/cber
// Function to search ud_bmp in listEqs, called by SetPhase0_Cell
// call form : SearchBmp(phase0_Nodes[i].listEqs,ud_bmp)
// Return: if pud_bmp not exist in listEqs, return -1
// else return eqID of CES whose cbm matches pud_bmp
uint32_t rfc_search_bmp(uint64_t *pud_bmp, uint32_t ul_table)
{
    uint32_t i;
    uint32_t ul_hash_index = 0, ul_index;
    rfc_phase_data_s *pst_acl_phase_data = &g_ix_rfc_table_base->st_acl_phase_data;
    uint32_t     *pul_hash = pst_acl_phase_data->ul_ces_hash;
    rfc_ces_s    *pst_ces = pst_acl_phase_data->st_ces;
    rfc_ces_s    *ces_tmp;   //指向 pst_ces结构体变量   临时变量
    uint64_t     *cbm_tmp;   //指向 pst_acl_phase_data->ud_cbm_data的临时变量
    uint32_t     ul_same_cbm = ACL_END_LINK;
    
    //tCES = ptrlistEqs->head;
    
    // get hashindex
    for (i = 0; i < pst_acl_phase_data->u_real_size; i++)
        ul_hash_index = (ul_hash_index + pud_bmp[i]) % MPP_MAX_ACL_HASH_SIZE;
      
    if (pul_hash[ul_hash_index] != ACL_END_LINK)
    {
        ul_index = pul_hash[ul_hash_index];
        
        while (ul_index != ACL_END_LINK)
        {
            ces_tmp = &pst_ces[ul_index];

            if (ul_same_cbm != ACL_END_LINK)
            {
                if (ul_same_cbm == ces_tmp->ul_cbm_index)
                {
                    if (ces_tmp->ul_table == ul_table)
                        return ces_tmp->ul_eq_id;
                }
            }
            else
            {
                // find same ud_bmp from hash table
                if (rfc_compare_bmp(pud_bmp, &pst_acl_phase_data->ud_cbm_data[ces_tmp->ul_cbm_index], pst_acl_phase_data->u_real_size) == RFCTRUE)
                {
                    if (ces_tmp->ul_table == ul_table)
                    {
                        return ces_tmp->ul_eq_id;
                    }
                        
                    else
                    {
                        ul_same_cbm = ces_tmp->ul_cbm_index;
                    }
                }
            }
            
            ul_index = ces_tmp->ul_next;
        }
    }
   
    if (pst_acl_phase_data->ul_ces_index + 1 >= MPP_MAX_ACL_CES_NUM)
    {
        return ACL_END_LINK;
    }
        
    if ((ul_same_cbm == ACL_END_LINK) && (pst_acl_phase_data->ul_cbm_index + pst_acl_phase_data->u_real_size >= MPP_MAX_ACL_CBM_NUM))
    {
        MC_PRINT (" (ul_same_cbm : %d, pst_acl_phase_data->ul_cbm_index : %d, pst_acl_phase_data->u_real_size : %d) &&\n", 
                ul_same_cbm, pst_acl_phase_data->ul_cbm_index, pst_acl_phase_data->u_real_size);
        return ACL_END_LINK;
    }

    ces_tmp = &pst_ces[pst_acl_phase_data->ul_ces_index];
    ces_tmp->ul_hash_index = ul_hash_index;
    ces_tmp->ul_next = pul_hash[ul_hash_index];
    ces_tmp->ul_eq_id = g_ix_rfc_table_base->pst_acl_commit->st_phase_nodes[ul_table].ul_eq_id++;
    ces_tmp->ul_table = ul_table;
    pul_hash[ul_hash_index] = pst_acl_phase_data->ul_ces_index++;
    if (ul_same_cbm == ACL_END_LINK)
    {
        ces_tmp->ul_cbm_index = pst_acl_phase_data->ul_cbm_index;
        pst_acl_phase_data->ul_cbm_index += pst_acl_phase_data->u_real_size;
        cbm_tmp = &pst_acl_phase_data->ud_cbm_data[ces_tmp->ul_cbm_index];
        for (i = 0; i < pst_acl_phase_data->u_real_size; i++)
            cbm_tmp[i] = pud_bmp[i];
    }
    else
    {
        ces_tmp->ul_cbm_index = ul_same_cbm;
    }
        
    return ces_tmp->ul_eq_id;
}