int nsim_cross_connect_enable_disable (nsim_main_t * nsm, u32 sw_if_index0, u32 sw_if_index1, int enable_disable) { vnet_sw_interface_t *sw; vnet_hw_interface_t *hw; int rv = 0; if (nsm->is_configured == 0) return VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE; /* Utterly wrong? */ if (pool_is_free_index (nsm->vnet_main->interface_main.sw_interfaces, sw_if_index0)) return VNET_API_ERROR_INVALID_SW_IF_INDEX; if (pool_is_free_index (nsm->vnet_main->interface_main.sw_interfaces, sw_if_index1)) return VNET_API_ERROR_INVALID_SW_IF_INDEX; /* Not a physical port? */ sw = vnet_get_sw_interface (nsm->vnet_main, sw_if_index0); if (sw->type != VNET_SW_INTERFACE_TYPE_HARDWARE) return VNET_API_ERROR_INVALID_SW_IF_INDEX; sw = vnet_get_sw_interface (nsm->vnet_main, sw_if_index1); if (sw->type != VNET_SW_INTERFACE_TYPE_HARDWARE) return VNET_API_ERROR_INVALID_SW_IF_INDEX; /* Add graph arcs for the input / wheel scraper node */ hw = vnet_get_hw_interface (nsm->vnet_main, sw_if_index0); nsm->output_next_index0 = vlib_node_add_next (nsm->vlib_main, nsim_input_node.index, hw->output_node_index); hw = vnet_get_hw_interface (nsm->vnet_main, sw_if_index1); nsm->output_next_index1 = vlib_node_add_next (nsm->vlib_main, nsim_input_node.index, hw->output_node_index); nsm->sw_if_index0 = sw_if_index0; nsm->sw_if_index1 = sw_if_index1; vnet_feature_enable_disable ("device-input", "nsim", sw_if_index0, enable_disable, 0, 0); vnet_feature_enable_disable ("device-input", "nsim", sw_if_index1, enable_disable, 0, 0); return rv; }
int sample_macswap_enable_disable (sample_main_t * sm, u32 sw_if_index, int enable_disable) { vnet_sw_interface_t * sw; int rv; u32 node_index = enable_disable ? sample_node.index : ~0; /* Utterly wrong? */ if (pool_is_free_index (sm->vnet_main->interface_main.sw_interfaces, sw_if_index)) return VNET_API_ERROR_INVALID_SW_IF_INDEX; /* Not a physical port? */ sw = vnet_get_sw_interface (sm->vnet_main, sw_if_index); if (sw->type != VNET_SW_INTERFACE_TYPE_HARDWARE) return VNET_API_ERROR_INVALID_SW_IF_INDEX; /* * Redirect pkts from the driver to the macswap node. * Returns VNET_API_ERROR_UNIMPLEMENTED if the h/w driver * doesn't implement the API. * * Node_index = ~0 => shut off redirection */ rv = vnet_hw_interface_rx_redirect_to_node (sm->vnet_main, sw_if_index, node_index); return rv; }
int nsim_output_feature_enable_disable (nsim_main_t * nsm, u32 sw_if_index, int enable_disable) { vnet_sw_interface_t *sw; vnet_hw_interface_t *hw; int rv = 0; if (nsm->is_configured == 0) return VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE; /* Utterly wrong? */ if (pool_is_free_index (nsm->vnet_main->interface_main.sw_interfaces, sw_if_index)) return VNET_API_ERROR_INVALID_SW_IF_INDEX; /* Not a physical port? */ sw = vnet_get_sw_interface (nsm->vnet_main, sw_if_index); if (sw->type != VNET_SW_INTERFACE_TYPE_HARDWARE) return VNET_API_ERROR_INVALID_SW_IF_INDEX; /* Add a graph arc for the input / wheel scraper node */ hw = vnet_get_hw_interface (nsm->vnet_main, sw_if_index); vec_validate_init_empty (nsm->output_next_index_by_sw_if_index, sw_if_index, ~0); /* Note: use the tx node, this pkt has already visited the output node... */ nsm->output_next_index_by_sw_if_index[sw_if_index] = vlib_node_add_next (nsm->vlib_main, nsim_input_node.index, hw->tx_node_index); vnet_feature_enable_disable ("interface-output", "nsim-output-feature", sw_if_index, enable_disable, 0, 0); return rv; }
/* SRv6 LocalSID instantiation and removal functions */ static int srv6_am_localsid_creation_fn (ip6_sr_localsid_t * localsid) { srv6_am_main_t *sm = &srv6_am_main; srv6_am_localsid_t *ls_mem = localsid->plugin_mem; adj_index_t nh_adj_index = ADJ_INDEX_INVALID; /* Step 1: Prepare xconnect adjacency for sending packets to the VNF */ /* Retrieve the adjacency corresponding to the (OIF, next_hop) */ nh_adj_index = adj_nbr_add_or_lock (FIB_PROTOCOL_IP6, VNET_LINK_IP6, &ls_mem->nh_addr, ls_mem->sw_if_index_out); if (nh_adj_index == ADJ_INDEX_INVALID) return -5; localsid->nh_adj = nh_adj_index; /* Step 2: Prepare inbound policy for packets returning from the VNF */ /* Sanitise the SW_IF_INDEX */ if (pool_is_free_index (sm->vnet_main->interface_main.sw_interfaces, ls_mem->sw_if_index_in)) return -3; vnet_sw_interface_t *sw = vnet_get_sw_interface (sm->vnet_main, ls_mem->sw_if_index_in); if (sw->type != VNET_SW_INTERFACE_TYPE_HARDWARE) return -3; int ret = vnet_feature_enable_disable ("ip6-unicast", "srv6-am-rewrite", ls_mem->sw_if_index_in, 1, 0, 0); if (ret != 0) return -1; return 0; }
static vlib_buffer_t * create_buffer_for_client_message (vlib_main_t * vm, u32 sw_if_index, dhcp6_pd_client_state_t * client_state, u32 type) { dhcp6_client_common_main_t *ccm = &dhcp6_client_common_main; vnet_main_t *vnm = vnet_get_main (); vlib_buffer_t *b; u32 bi; ip6_header_t *ip; udp_header_t *udp; dhcpv6_header_t *dhcp; ip6_address_t src_addr; u32 dhcp_opt_len = 0; client_state->transaction_start = vlib_time_now (vm); u32 n_prefixes; u32 i; vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index); vnet_sw_interface_t *sup_sw = vnet_get_sup_sw_interface (vnm, sw_if_index); vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index); /* Interface(s) down? */ if ((hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) == 0) return NULL; if ((sup_sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0) return NULL; if ((sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0) return NULL; /* Get a link-local address */ src_addr = ip6_neighbor_get_link_local_address (sw_if_index); if (src_addr.as_u8[0] != 0xfe) { clib_warning ("Could not find source address to send DHCPv6 packet"); return NULL; } if (vlib_buffer_alloc (vm, &bi, 1) != 1) { clib_warning ("Buffer allocation failed"); return NULL; } b = vlib_get_buffer (vm, bi); vnet_buffer (b)->sw_if_index[VLIB_RX] = sw_if_index; vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index; client_state->adj_index = adj_mcast_add_or_lock (FIB_PROTOCOL_IP6, VNET_LINK_IP6, sw_if_index); vnet_buffer (b)->ip.adj_index[VLIB_TX] = client_state->adj_index; b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; ip = (ip6_header_t *) vlib_buffer_get_current (b); udp = (udp_header_t *) (ip + 1); dhcp = (dhcpv6_header_t *) (udp + 1); ip->src_address = src_addr; ip->hop_limit = 255; ip->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32 (0x6 << 28); ip->payload_length = 0; ip->protocol = IP_PROTOCOL_UDP; udp->src_port = clib_host_to_net_u16 (DHCPV6_CLIENT_PORT); udp->dst_port = clib_host_to_net_u16 (DHCPV6_SERVER_PORT); udp->checksum = 0; udp->length = 0; dhcp->msg_type = type; dhcp->xid[0] = (client_state->transaction_id & 0x00ff0000) >> 16; dhcp->xid[1] = (client_state->transaction_id & 0x0000ff00) >> 8; dhcp->xid[2] = (client_state->transaction_id & 0x000000ff) >> 0; void *d = (void *) dhcp->data; dhcpv6_option_t *duid; dhcpv6_elapsed_t *elapsed; dhcpv6_ia_header_t *ia_hdr; dhcpv6_ia_opt_pd_t *opt_pd; if (type == DHCPV6_MSG_SOLICIT || type == DHCPV6_MSG_REQUEST || type == DHCPV6_MSG_RENEW || type == DHCPV6_MSG_REBIND || type == DHCPV6_MSG_RELEASE) { duid = (dhcpv6_option_t *) d; duid->option = clib_host_to_net_u16 (DHCPV6_OPTION_CLIENTID); duid->length = clib_host_to_net_u16 (CLIENT_DUID_LENGTH); clib_memcpy (duid + 1, client_duid.bin_string, CLIENT_DUID_LENGTH); d += sizeof (*duid) + CLIENT_DUID_LENGTH; if (client_state->params.server_index != ~0) { server_id_t *se = &ccm->server_ids[client_state->params.server_index]; duid = (dhcpv6_option_t *) d; duid->option = clib_host_to_net_u16 (DHCPV6_OPTION_SERVERID); duid->length = clib_host_to_net_u16 (se->len); clib_memcpy (duid + 1, se->data, se->len); d += sizeof (*duid) + se->len; } elapsed = (dhcpv6_elapsed_t *) d; elapsed->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_ELAPSED_TIME); elapsed->opt.length = clib_host_to_net_u16 (sizeof (*elapsed) - sizeof (elapsed->opt)); elapsed->elapsed_10ms = 0; client_state->elapsed_pos = (char *) &elapsed->elapsed_10ms - (char *) vlib_buffer_get_current (b); d += sizeof (*elapsed); ia_hdr = (dhcpv6_ia_header_t *) d; ia_hdr->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_IA_PD); ia_hdr->iaid = clib_host_to_net_u32 (DHCPV6_CLIENT_IAID); ia_hdr->t1 = clib_host_to_net_u32 (client_state->params.T1); ia_hdr->t2 = clib_host_to_net_u32 (client_state->params.T2); d += sizeof (*ia_hdr); n_prefixes = vec_len (client_state->params.prefixes); ia_hdr->opt.length = clib_host_to_net_u16 (sizeof (*ia_hdr) + n_prefixes * sizeof (*opt_pd) - sizeof (ia_hdr->opt)); for (i = 0; i < n_prefixes; i++) { dhcp6_pd_send_client_message_params_prefix_t *pref = &client_state->params.prefixes[i]; opt_pd = (dhcpv6_ia_opt_pd_t *) d; opt_pd->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_IAPREFIX); opt_pd->opt.length = clib_host_to_net_u16 (sizeof (*opt_pd) - sizeof (opt_pd->opt)); opt_pd->addr = pref->prefix; opt_pd->prefix = pref->prefix_length; opt_pd->valid = clib_host_to_net_u32 (pref->valid_lt); opt_pd->preferred = clib_host_to_net_u32 (pref->preferred_lt); d += sizeof (*opt_pd); } } else { clib_warning ("State not implemented"); } dhcp_opt_len = ((u8 *) d) - dhcp->data; udp->length = clib_host_to_net_u16 (sizeof (*udp) + sizeof (*dhcp) + dhcp_opt_len); ip->payload_length = udp->length; b->current_length = sizeof (*ip) + sizeof (*udp) + sizeof (*dhcp) + dhcp_opt_len; ip->dst_address = all_dhcp6_relay_agents_and_servers; return b; }