static switch_status_t switch_api_init_default_acl_entries( switch_device_t device) { switch_acl_system_key_value_pair_t acl_kvp[5]; switch_acl_action_params_t action_params; switch_acl_opt_action_params_t opt_action_params; switch_handle_t acl_handle; switch_handle_t handle; int priority = 100; switch_default_acl_t *dacl = &_switch_system_acl_data[device][0]; memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); // system acl for dropped packets dacl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DROP; dacl->acl_kvp[0].value.drop_flag = 1; dacl->acl_kvp[0].mask.u.mask = 0xFF; dacl->priority = priority++; dacl->key_value_count = 1; memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); dacl++; // port vlan mapping miss, drop dacl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_PORT_VLAN_MAPPING_MISS; dacl->acl_kvp[0].value.port_vlan_mapping_miss = 1; dacl->acl_kvp[0].mask.u.mask = 0xFF; dacl->priority = priority++; dacl->key_value_count = 1; memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); dacl->action_params.drop.reason_code = DROP_PORT_VLAN_MAPPING_MISS; dacl++; // STP state == blocked, drop dacl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_STP_STATE; dacl->acl_kvp[0].value.stp_state = SWITCH_PORT_STP_STATE_BLOCKING; dacl->acl_kvp[0].mask.u.mask = 0xFF; dacl->priority = priority++; dacl->key_value_count = 1; memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); dacl->action_params.drop.reason_code = DROP_STP_STATE_BLOCKING; dacl++; // STP state == learning, drop dacl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_STP_STATE; dacl->acl_kvp[0].value.stp_state = SWITCH_PORT_STP_STATE_LEARNING; dacl->acl_kvp[0].mask.u.mask = 0xFF; dacl->priority = priority++; dacl->key_value_count = 1; memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); dacl->action_params.drop.reason_code = DROP_STP_STATE_LEARNING; dacl++; // ACL deny, drop dacl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ACL_DENY; dacl->acl_kvp[0].value.acl_deny = 1; dacl->acl_kvp[0].mask.u.mask = 0xFF; dacl->priority = priority++; dacl->key_value_count = 1; memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); dacl->action_params.drop.reason_code = DROP_ACL_DENY; dacl++; // URPF check fail, drop dacl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_URPF_CHECK; dacl->acl_kvp[0].value.urpf_check_fail = 1; dacl->acl_kvp[0].mask.u.mask = 0xFF; dacl->priority = priority++; dacl->key_value_count = 1; memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); dacl->action_params.drop.reason_code = DROP_URPF_CHECK_FAIL; dacl++; // same if check fail, drop dacl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_IF_CHECK; dacl->acl_kvp[0].value.if_check = 0; dacl->acl_kvp[0].mask.u.mask = 0xFFFF; dacl->acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_BD_CHECK; dacl->acl_kvp[1].value.bd_check = 0; dacl->acl_kvp[1].mask.u.mask = 0xFFFF; dacl->acl_kvp[2].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; dacl->acl_kvp[2].value.routed = 0; dacl->acl_kvp[2].mask.u.mask = 0xFFFF; dacl->acl_kvp[3].field = SWITCH_ACL_SYSTEM_FIELD_TUNNEL_IF_CHECK; dacl->acl_kvp[3].value.tunnel_if_check = 0; dacl->acl_kvp[3].mask.u.mask = 0xFFFF; dacl->priority = priority++; dacl->key_value_count = 4; memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); dacl->action_params.drop.reason_code = DROP_SAME_IFINDEX; dacl++; // egress ifindex is drop ifindex, drop dacl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX; dacl->acl_kvp[0].value.out_ifindex = switch_api_drop_ifindex(); dacl->acl_kvp[0].mask.u.mask = 0xFFFF; dacl->priority = priority++; dacl->key_value_count = 1; memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); dacl->action_params.drop.reason_code = DROP_IFINDEX; dacl++; switch_system_acl_entries_add(device); // routed, ttl == 1, egress_ifindex == cpu, permit acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; acl_kvp[0].value.routed = true; acl_kvp[0].mask.u.mask = 0xFF; acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_TTL; acl_kvp[1].value.ttl = 1; acl_kvp[1].mask.u.mask = 0xFF; acl_kvp[2].field = SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX; acl_kvp[2].value.out_ifindex = switch_api_cpu_glean_ifindex(); acl_kvp[2].mask.u.mask = 0xFFFF; memset(&action_params, 0, sizeof(switch_acl_action_params_t)); switch_api_acl_rule_create(device, acl_handle, priority++, 3, acl_kvp, SWITCH_ACL_ACTION_PERMIT, &action_params, &opt_action_params, &handle); // routed, ttl == 1, redirect to cpu acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; acl_kvp[0].value.routed = true; acl_kvp[0].mask.u.mask = 0xFF; acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_TTL; acl_kvp[1].value.ttl = 1; acl_kvp[1].mask.u.mask = 0xFF; memset(&action_params, 0, sizeof(switch_acl_action_params_t)); action_params.cpu_redirect.reason_code = SWITCH_HOSTIF_REASON_CODE_TTL_ERROR; switch_api_acl_rule_create(device, acl_handle, priority++, 2, acl_kvp, SWITCH_ACL_ACTION_REDIRECT_TO_CPU, &action_params, &opt_action_params, &handle); // routed, ipv6_src_is_link_local == 1, egress_ifindex == cpu, permit acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; acl_kvp[0].value.routed = true; acl_kvp[0].mask.u.mask = 0xFF; acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_LINK_LOCAL; acl_kvp[1].value.src_is_link_local = 1; acl_kvp[1].mask.u.mask = 0xFF; acl_kvp[2].field = SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX; acl_kvp[2].value.out_ifindex = switch_api_cpu_glean_ifindex(); acl_kvp[2].mask.u.mask = 0xFFFF; memset(&action_params, 0, sizeof(switch_acl_action_params_t)); action_params.cpu_redirect.reason_code = SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL; switch_api_acl_rule_create(device, acl_handle, priority++, 3, acl_kvp, SWITCH_ACL_ACTION_PERMIT, &action_params, &opt_action_params, &handle); // routed, ipv6_src_is_link_local == 1, redirect to cpu acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; acl_kvp[0].value.routed = true; acl_kvp[0].mask.u.mask = 0xFF; acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_LINK_LOCAL; acl_kvp[1].value.src_is_link_local = 1; acl_kvp[1].mask.u.mask = 0xFF; memset(&action_params, 0, sizeof(switch_acl_action_params_t)); action_params.cpu_redirect.reason_code = SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL; switch_api_acl_rule_create(device, acl_handle, priority++, 2, acl_kvp, SWITCH_ACL_ACTION_REDIRECT_TO_CPU, &action_params, &opt_action_params, &handle); // routed, ingress bd == egress bd, copy to cpu acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; acl_kvp[0].value.routed = true; acl_kvp[0].mask.u.mask = 0xFF; acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_BD_CHECK; acl_kvp[1].value.bd_check = 0; acl_kvp[1].mask.u.mask = 0xFFFF; memset(&action_params, 0, sizeof(switch_acl_action_params_t)); action_params.cpu_redirect.reason_code = SWITCH_HOSTIF_REASON_CODE_ICMP_REDIRECT; switch_api_acl_rule_create(device, acl_handle, priority++, 2, acl_kvp, SWITCH_ACL_ACTION_COPY_TO_CPU, &action_params, &opt_action_params, &handle); // l3_copy to cpu acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_L3_COPY; acl_kvp[0].value.l3_copy = true; acl_kvp[0].mask.u.mask = 0xFF; memset(&action_params, 0, sizeof(switch_acl_action_params_t)); switch_api_acl_rule_create(device, acl_handle, priority++, 1, acl_kvp, SWITCH_ACL_ACTION_COPY_TO_CPU, &action_params, &opt_action_params, &handle); switch_default_acl_t *egr_acl = &_switch_egress_acl_data[device][0]; // set acl handler and priority for egress mtu check rule egr_acl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_EGRESS, SWITCH_ACL_TYPE_EGRESS_SYSTEM); egr_acl->priority = priority++; egr_acl->key_value_count = 1; switch_api_acl_reference(device, egr_acl->acl_handle, 0); egr_acl++; // set acl handler and priority for egress dod rule egr_acl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_EGRESS, SWITCH_ACL_TYPE_EGRESS_SYSTEM); egr_acl->priority = priority++; egr_acl->key_value_count = 1; switch_api_acl_reference(device, egr_acl->acl_handle, 0); egr_acl++; egr_acl->acl_handle = switch_api_acl_list_create( device, SWITCH_API_DIRECTION_EGRESS, SWITCH_ACL_TYPE_EGRESS_SYSTEM); egr_acl->priority = priority++; egr_acl->key_value_count = 1; switch_api_acl_reference(device, egr_acl->acl_handle, 0); switch_egress_acl_entries_add(device); return SWITCH_STATUS_SUCCESS; }
switch_status_t switch_nhop_ifindex_get(switch_handle_t nhop_handle, switch_ifindex_t *ifindex, bool *flood, uint32_t *mc_index) { switch_nhop_info_t *nhop_info = NULL; switch_interface_info_t *intf_info = NULL; switch_neighbor_info_t *neighbor_info = NULL; switch_api_neighbor_t *neighbor = NULL; switch_api_mac_entry_t mac_entry; switch_mac_info_t *mac_info = NULL; switch_handle_t neighbor_handle; switch_bd_info_t *bd_info = NULL; switch_port_info_t *tmp_port_info = NULL; switch_lag_info_t *tmp_lag_info = NULL; switch_interface_info_t *tmp_intf_info = NULL; switch_api_mac_entry_t *tmp_mac_entry = NULL; switch_handle_type_t handle_type = 0; switch_handle_t encap_if; switch_spath_info_t *spath_info = NULL; nhop_info = switch_nhop_get(nhop_handle); if (!nhop_info) { return SWITCH_STATUS_INVALID_HANDLE; } spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); if (!intf_info) { return SWITCH_STATUS_INVALID_HANDLE; } *ifindex = intf_info->ifindex; *flood = FALSE; *mc_index = 0; if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { encap_if = SWITCH_INTF_TUNNEL_ENCAP_OUT_IF(intf_info); intf_info = switch_api_interface_get(encap_if); if (!intf_info) { return SWITCH_STATUS_INVALID_HANDLE; } *ifindex = intf_info->ifindex; SWITCH_API_TRACE("%s:%d ifindex for tunnel interface: %x", __FUNCTION__, __LINE__, *ifindex); } if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_VLAN) { neighbor_handle = spath_info->neighbor_handle; if (neighbor_handle == SWITCH_API_INVALID_HANDLE || neighbor_handle == 0) { *ifindex = switch_api_cpu_glean_ifindex(); } else { neighbor_info = switch_neighbor_info_get(neighbor_handle); if (!neighbor_info) { return SWITCH_STATUS_INVALID_HANDLE; } neighbor = &neighbor_info->neighbor; memset(&mac_entry, 0, sizeof(switch_api_mac_entry_t)); mac_entry.vlan_handle = intf_info->bd_handle; memcpy(&mac_entry.mac, &neighbor->mac_addr, ETH_LEN); mac_info = switch_mac_table_entry_find(&mac_entry); if (!mac_info) { bd_info = switch_bd_get(intf_info->bd_handle); if (!bd_info) { return SWITCH_STATUS_INVALID_HANDLE; } *mc_index = handle_to_id(bd_info->uuc_mc_index); *flood = TRUE; } else { tmp_mac_entry = &mac_info->mac_entry; handle_type = switch_handle_get_type(tmp_mac_entry->handle); switch (handle_type) { case SWITCH_HANDLE_TYPE_PORT: tmp_port_info = switch_api_port_get_internal(tmp_mac_entry->handle); if (!tmp_port_info) { return SWITCH_STATUS_INVALID_HANDLE; } *ifindex = tmp_port_info->ifindex; break; case SWITCH_HANDLE_TYPE_LAG: tmp_lag_info = switch_api_lag_get_internal(tmp_mac_entry->handle); if (!tmp_lag_info) { return SWITCH_STATUS_INVALID_HANDLE; } *ifindex = tmp_lag_info->ifindex; break; case SWITCH_HANDLE_TYPE_INTERFACE: tmp_intf_info = switch_api_interface_get(tmp_mac_entry->handle); if (!tmp_intf_info) { return SWITCH_STATUS_INVALID_HANDLE; } *ifindex = tmp_intf_info->ifindex; break; default: return SWITCH_STATUS_INVALID_HANDLE; } } } } return SWITCH_STATUS_SUCCESS; }