static clib_error_t * nsim_init (vlib_main_t * vm) { nsim_main_t *nsm = &nsim_main; clib_error_t *error = 0; u8 *name; nsm->vlib_main = vm; nsm->vnet_main = vnet_get_main (); name = format (0, "nsim_%08x%c", api_version, 0); /* Ask for a correctly-sized block of API message decode slots */ nsm->msg_id_base = vl_msg_api_get_msg_ids ((char *) name, VL_MSG_FIRST_AVAILABLE); error = nsim_plugin_api_hookup (vm); /* Add our API messages to the global name_crc hash table */ setup_message_id_table (nsm, &api_main); vec_free (name); return error; }
/** * adj_mcast_update_rewrite * * Update the adjacency's rewrite string. A NULL string implies the * rewrite is reset (i.e. when ARP/ND entry is gone). * NB: the adj being updated may be handling traffic in the DP. */ void adj_mcast_update_rewrite (adj_index_t adj_index, u8 *rewrite, u8 offset) { ip_adjacency_t *adj; ASSERT(ADJ_INDEX_INVALID != adj_index); adj = adj_get(adj_index); /* * update the adj's rewrite string and build the arc * from the rewrite node to the interface's TX node */ adj_nbr_update_rewrite_internal(adj, IP_LOOKUP_NEXT_MCAST, adj_get_mcast_node(adj->ia_nh_proto), vnet_tx_node_index_for_sw_interface( vnet_get_main(), adj->rewrite_header.sw_if_index), rewrite); /* * set the offset corresponding to the mcast IP address rewrite */ adj->rewrite_header.dst_mcast_offset = offset; }
static clib_error_t * ioam_export_init (vlib_main_t * vm) { ioam_export_main_t *em = &ioam_export_main; clib_error_t *error = 0; u8 *name; u32 node_index = export_node.index; vlib_node_t *ip6_hbyh_node = NULL; em->vlib_main = vm; em->vnet_main = vnet_get_main (); em->set_id = IPFIX_IOAM_EXPORT_ID; ioam_export_reset_next_node (em); name = format (0, "ioam_export_%08x%c", api_version, 0); /* Ask for a correctly-sized block of API message decode slots */ em->msg_id_base = vl_msg_api_get_msg_ids ((char *) name, VL_MSG_FIRST_AVAILABLE); em->unix_time_0 = (u32) time (0); /* Store starting time */ em->vlib_time_0 = vlib_time_now (vm); error = ioam_export_plugin_api_hookup (vm); /* Add our API messages to the global name_crc hash table */ setup_message_id_table (em, &api_main); /* Hook this export node to ip6-hop-by-hop */ ip6_hbyh_node = vlib_get_node_by_name (vm, (u8 *) "ip6-hop-by-hop"); em->my_hbh_slot = vlib_node_add_next (vm, ip6_hbyh_node->index, node_index); vec_free (name); return error; }
clib_error_t *replication_init (vlib_main_t *vm) { replication_main_t * rm = &replication_main; vlib_buffer_main_t * bm = vm->buffer_main; vlib_buffer_free_list_t * fl; __attribute__((unused)) replication_context_t * ctx; vlib_thread_main_t * tm = vlib_get_thread_main(); rm->vlib_main = vm; rm->vnet_main = vnet_get_main(); rm->recycle_list_index = vlib_buffer_create_free_list (vm, 1024 /* fictional */, "replication-recycle"); fl = pool_elt_at_index (bm->buffer_free_list_pool, rm->recycle_list_index); fl->buffers_added_to_freelist_function = replication_recycle_callback; // Verify the replication context is the expected size ASSERT(sizeof(replication_context_t) == 128); // 2 cache lines vec_validate (rm->contexts, tm->n_vlib_mains - 1); return 0; }
static clib_error_t * mtu_cmd (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { vnet_main_t * vnm = vnet_get_main(); u32 hw_if_index, mtu; u32 flags = ETHERNET_INTERFACE_FLAG_MTU; if (unformat (input, "%d %U", &mtu, unformat_ethernet_interface, vnm, &hw_if_index)) { vnet_hw_interface_t * hi = vnet_get_hw_interface (vnm, hw_if_index); if (mtu < ETHERNET_MIN_PACKET_BYTES) return clib_error_return (0, "Invalid mtu (%d): " "must be >= min pkt bytes (%d)", mtu, hi->min_packet_bytes); if (mtu > ETHERNET_MAX_PACKET_BYTES) return clib_error_return (0, "Invalid mtu (%d): must be <= 9216", mtu); if (hi->max_packet_bytes != mtu) { hi->max_packet_bytes = mtu; ethernet_set_flags (vnm, hw_if_index, flags); } } else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); return 0; }
static clib_error_t * promiscuous_cmd (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { vnet_main_t * vnm = vnet_get_main(); u32 hw_if_index; u32 flags = ETHERNET_INTERFACE_FLAG_ACCEPT_ALL; if (unformat (input, "on %U", unformat_ethernet_interface, vnm, &hw_if_index)) { ethernet_set_flags (vnm, hw_if_index, flags); } else if (unformat (input, "off %U", unformat_ethernet_interface, vnm, &hw_if_index)) { flags = 0; ethernet_set_flags (vnm, hw_if_index, flags); } else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); return 0; }
static u8 * format_vxlan_tunnel_ref (u8 * s, va_list * args) { index_t vxri = va_arg (*args, u32); vxlan_tunnel_ref_t *vxr; vxr = vxlan_tunnel_ref_get (vxri); s = format (s, "[%U locks:%d]", format_vnet_sw_if_index_name, vnet_get_main (), vxr->vxr_sw_if_index, vxr->vxr_locks); return (s); }
static clib_error_t * netmap_create_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { unformat_input_t _line_input, * line_input = &_line_input; u8 * host_if_name = NULL; u8 hwaddr [6]; u8 * hw_addr_ptr = 0; int r; u8 is_pipe = 0; u8 is_master = 0; u32 sw_if_index = ~0; /* Get a line of input. */ if (! unformat_user (input, unformat_line_input, line_input)) return 0; while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { if (unformat (line_input, "name %s", &host_if_name)) ; else if (unformat (line_input, "hw-addr %U", unformat_ethernet_address, hwaddr)) hw_addr_ptr = hwaddr; else if (unformat (line_input, "pipe")) is_pipe = 1; else if (unformat (line_input, "master")) is_master = 1; else if (unformat (line_input, "slave")) is_master = 0; else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); } unformat_free (line_input); if (host_if_name == NULL) return clib_error_return (0, "missing host interface name"); r = netmap_create_if(vm, host_if_name, hw_addr_ptr, is_pipe, is_master, &sw_if_index); if (r == VNET_API_ERROR_SYSCALL_ERROR_1) return clib_error_return(0, "%s (errno %d)", strerror (errno), errno); if (r == VNET_API_ERROR_INVALID_INTERFACE) return clib_error_return(0, "Invalid interface name"); if (r == VNET_API_ERROR_SUBIF_ALREADY_EXISTS) return clib_error_return(0, "Interface already exists"); vlib_cli_output(vm, "%U\n", format_vnet_sw_if_index_name, vnet_get_main(), sw_if_index); return 0; }
/* * cnat_ports_init */ clib_error_t *cnat_ports_init(vlib_main_t *vm) { cnat_ports_main_t *mp = &cnat_ports_main; mp->vlib_main = vm; mp->vnet_main = vnet_get_main(); /* suppress crypto-random port numbering */ #ifdef SOON if (spp_get_int_prop("no_crypto_random_ports") == 0) crypto_random32(&seed); #endif return 0; }
clib_error_t * vnet_main_init (vlib_main_t * vm) { vnet_main_t *vnm = vnet_get_main (); clib_error_t *error; u32 hw_if_index; vnet_hw_interface_t *hw; if ((error = vlib_call_init_function (vm, vnet_interface_init))) return error; if ((error = vlib_call_init_function (vm, fib_module_init))) return error; if ((error = vlib_call_init_function (vm, mfib_module_init))) return error; if ((error = vlib_call_init_function (vm, ip_main_init))) return error; if ((error = vlib_call_init_function (vm, ip4_lookup_init))) return error; if ((error = vlib_call_init_function (vm, ip6_lookup_init))) return error; if ((error = vlib_call_init_function (vm, mpls_init))) return error; vnm->vlib_main = vm; hw_if_index = vnet_register_interface (vnm, vnet_local_interface_device_class.index, /* instance */ 0, vnet_local_interface_hw_class.index, /* instance */ 0); hw = vnet_get_hw_interface (vnm, hw_if_index); vnm->local_interface_hw_if_index = hw_if_index; vnm->local_interface_sw_if_index = hw->sw_if_index; /* the local interface is used as an input interface when decapping from * an IPSEC tunnel. so it needs to be IP enabled */ ip4_sw_interface_enable_disable (hw->sw_if_index, 1); ip6_sw_interface_enable_disable (hw->sw_if_index, 1); return 0; }
static clib_error_t * qos_mark_cli (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { qos_egress_map_id_t map_id; u32 sw_if_index, qs; vnet_main_t *vnm; int rv, enable; vnm = vnet_get_main (); map_id = ~0; qs = 0xff; enable = 1; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "id %d", &map_id)) ; else if (unformat (input, "disable")) enable = 0; else if (unformat (input, "%U", unformat_qos_source, &qs)) ; else if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index)) ; else break; } if (~0 == sw_if_index) return clib_error_return (0, "interface must be specified"); if (0xff == qs) return clib_error_return (0, "output location must be specified"); if (enable) rv = qos_mark_enable (sw_if_index, qs, map_id); else rv = qos_mark_disable (sw_if_index, qs); if (0 == rv) return (NULL); return clib_error_return (0, "Failed to map interface"); }
/* * adj_mcast_add_or_lock * * The next_hop address here is used for source address selection in the DP. * The mcast adj is added to an interface's connected prefix, the next-hop * passed here is the local prefix on the same interface. */ adj_index_t adj_mcast_add_or_lock (fib_protocol_t proto, vnet_link_t link_type, u32 sw_if_index) { ip_adjacency_t * adj; vec_validate_init_empty(adj_mcasts[proto], sw_if_index, ADJ_INDEX_INVALID); if (ADJ_INDEX_INVALID == adj_mcasts[proto][sw_if_index]) { vnet_main_t *vnm; vnm = vnet_get_main(); adj = adj_alloc(proto); adj->lookup_next_index = IP_LOOKUP_NEXT_MCAST; adj->ia_nh_proto = proto; adj->ia_link = link_type; adj_mcasts[proto][sw_if_index] = adj_get_index(adj); adj_lock(adj_get_index(adj)); vnet_rewrite_init(vnm, sw_if_index, link_type, adj_get_mcast_node(proto), vnet_tx_node_index_for_sw_interface(vnm, sw_if_index), &adj->rewrite_header); /* * we need a rewrite where the destination IP address is converted * to the appropriate link-layer address. This is interface specific. * So ask the interface to do it. */ vnet_update_adjacency_for_sw_interface(vnm, sw_if_index, adj_get_index(adj)); } else { adj = adj_get(adj_mcasts[proto][sw_if_index]); adj_lock(adj_get_index(adj)); } return (adj_get_index(adj)); }
static clib_error_t * virtio_pci_delete_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { unformat_input_t _line_input, *line_input = &_line_input; u32 sw_if_index = ~0; vnet_hw_interface_t *hw; virtio_main_t *vim = &virtio_main; virtio_if_t *vif; vnet_main_t *vnm = vnet_get_main (); /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return 0; while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { if (unformat (line_input, "sw_if_index %d", &sw_if_index)) ; else if (unformat (line_input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index)) ; else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); } unformat_free (line_input); if (sw_if_index == ~0) return clib_error_return (0, "please specify interface name or sw_if_index"); hw = vnet_get_sup_hw_interface (vnm, sw_if_index); if (hw == NULL || virtio_device_class.index != hw->dev_class_index) return clib_error_return (0, "not a virtio interface"); vif = pool_elt_at_index (vim->interfaces, hw->dev_instance); if (virtio_pci_delete_if (vm, vif) < 0) return clib_error_return (0, "not a virtio pci interface"); return 0; }
static void vl_api_create_vhost_user_if_t_handler (vl_api_create_vhost_user_if_t * mp) { int rv = 0; vl_api_create_vhost_user_if_reply_t *rmp; u32 sw_if_index = (u32) ~ 0; vnet_main_t *vnm = vnet_get_main (); vlib_main_t *vm = vlib_get_main (); u64 features = (u64) ~ (0ULL); u64 disabled_features = (u64) (0ULL); if (mp->disable_mrg_rxbuf) disabled_features = (1ULL << FEAT_VIRTIO_NET_F_MRG_RXBUF); if (mp->disable_indirect_desc) disabled_features |= (1ULL << FEAT_VIRTIO_F_INDIRECT_DESC); features &= ~disabled_features; rv = vhost_user_create_if (vnm, vm, (char *) mp->sock_filename, mp->is_server, &sw_if_index, features, mp->renumber, ntohl (mp->custom_dev_instance), (mp->use_custom_mac) ? mp->mac_address : NULL); /* Remember an interface tag for the new interface */ if (rv == 0) { /* If a tag was supplied... */ if (mp->tag[0]) { /* Make sure it's a proper C-string */ mp->tag[ARRAY_LEN (mp->tag) - 1] = 0; u8 *tag = format (0, "%s%c", mp->tag, 0); vnet_set_sw_interface_tag (vnm, tag, sw_if_index); } } /* *INDENT-OFF* */ REPLY_MACRO2(VL_API_CREATE_VHOST_USER_IF_REPLY, ({ rmp->sw_if_index = ntohl (sw_if_index); }));
/** * adj_mcast_midchain_update_rewrite * * Update the adjacency's rewrite string. A NULL string implies the * rewrite is reset (i.e. when ARP/ND entry is gone). * NB: the adj being updated may be handling traffic in the DP. */ void adj_mcast_midchain_update_rewrite (adj_index_t adj_index, adj_midchain_fixup_t fixup, const void *fixup_data, adj_flags_t flags, u8 *rewrite, u8 offset, u32 mask) { ip_adjacency_t *adj; ASSERT(ADJ_INDEX_INVALID != adj_index); adj = adj_get(adj_index); /* * one time only update. since we don't support changing the tunnel * src,dst, this is all we need. */ ASSERT(adj->lookup_next_index == IP_LOOKUP_NEXT_MCAST); /* * tunnels can always provide a rewrite. */ ASSERT(NULL != rewrite); adj_midchain_setup(adj_index, fixup, fixup_data, flags); /* * update the adj's rewrite string and build the arc * from the rewrite node to the interface's TX node */ adj_nbr_update_rewrite_internal(adj, IP_LOOKUP_NEXT_MCAST_MIDCHAIN, adj_get_mcast_node(adj->ia_nh_proto), vnet_tx_node_index_for_sw_interface( vnet_get_main(), adj->rewrite_header.sw_if_index), rewrite); adj->rewrite_header.dst_mcast_offset = offset; }
static clib_error_t * mpls_interface_enable_disable (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { vnet_main_t * vnm = vnet_get_main(); clib_error_t * error = 0; u32 sw_if_index, enable; int rv; sw_if_index = ~0; if (! unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index)) { error = clib_error_return (0, "unknown interface `%U'", format_unformat_error, input); goto done; } if (unformat (input, "enable")) enable = 1; else if (unformat (input, "disable")) enable = 0; else { error = clib_error_return (0, "expected 'enable' or 'disable'", format_unformat_error, input); goto done; } rv = mpls_sw_interface_enable_disable(&mpls_main, sw_if_index, enable, 0); if (VNET_API_ERROR_NO_SUCH_FIB == rv) error = clib_error_return (0, "default MPLS table must be created first"); done: return error; }
clib_error_t * vnet_main_init (vlib_main_t * vm) { vnet_main_t * vnm = vnet_get_main(); clib_error_t * error; u32 hw_if_index; vnet_hw_interface_t * hw; if ((error = vlib_call_init_function (vm, vnet_interface_init))) return error; vnm->vlib_main = vm; hw_if_index = vnet_register_interface (vnm, vnet_local_interface_device_class.index, /* instance */ 0, vnet_local_interface_hw_class.index, /* instance */ 0); hw = vnet_get_hw_interface (vnm, hw_if_index); vnm->local_interface_hw_if_index = hw_if_index; vnm->local_interface_sw_if_index = hw->sw_if_index; return 0; }
always_inline uword adj_midchain_tx_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame, int interface_count) { u32 * from, * to_next, n_left_from, n_left_to_next; u32 next_index; vnet_main_t *vnm = vnet_get_main (); vnet_interface_main_t *im = &vnm->interface_main; u32 thread_index = vm->thread_index; /* Vector of buffer / pkt indices we're supposed to process */ from = vlib_frame_vector_args (frame); /* Number of buffers / pkts */ n_left_from = frame->n_vectors; /* Speculatively send the first buffer to the last disposition we used */ next_index = node->cached_next_index; while (n_left_from > 0) { /* set up to enqueue to our disposition with index = next_index */ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from >= 8 && n_left_to_next > 4) { u32 bi0, adj_index0, next0; const ip_adjacency_t * adj0; const dpo_id_t *dpo0; vlib_buffer_t * b0; u32 bi1, adj_index1, next1; const ip_adjacency_t * adj1; const dpo_id_t *dpo1; vlib_buffer_t * b1; u32 bi2, adj_index2, next2; const ip_adjacency_t * adj2; const dpo_id_t *dpo2; vlib_buffer_t * b2; u32 bi3, adj_index3, next3; const ip_adjacency_t * adj3; const dpo_id_t *dpo3; vlib_buffer_t * b3; /* Prefetch next iteration. */ { vlib_buffer_t * p4, * p5; vlib_buffer_t * p6, * p7; p4 = vlib_get_buffer (vm, from[4]); p5 = vlib_get_buffer (vm, from[5]); p6 = vlib_get_buffer (vm, from[6]); p7 = vlib_get_buffer (vm, from[7]); vlib_prefetch_buffer_header (p4, LOAD); vlib_prefetch_buffer_header (p5, LOAD); vlib_prefetch_buffer_header (p6, LOAD); vlib_prefetch_buffer_header (p7, LOAD); } bi0 = from[0]; to_next[0] = bi0; bi1 = from[1]; to_next[1] = bi1; bi2 = from[2]; to_next[2] = bi2; bi3 = from[3]; to_next[3] = bi3; from += 4; to_next += 4; n_left_from -= 4; n_left_to_next -= 4; b0 = vlib_get_buffer(vm, bi0); b1 = vlib_get_buffer(vm, bi1); b2 = vlib_get_buffer(vm, bi2); b3 = vlib_get_buffer(vm, bi3); /* Follow the DPO on which the midchain is stacked */ adj_index0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX]; adj_index1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX]; adj_index2 = vnet_buffer(b2)->ip.adj_index[VLIB_TX]; adj_index3 = vnet_buffer(b3)->ip.adj_index[VLIB_TX]; adj0 = adj_get(adj_index0); adj1 = adj_get(adj_index1); adj2 = adj_get(adj_index2); adj3 = adj_get(adj_index3); dpo0 = &adj0->sub_type.midchain.next_dpo; dpo1 = &adj1->sub_type.midchain.next_dpo; dpo2 = &adj2->sub_type.midchain.next_dpo; dpo3 = &adj3->sub_type.midchain.next_dpo; next0 = dpo0->dpoi_next_node; next1 = dpo1->dpoi_next_node; next2 = dpo2->dpoi_next_node; next3 = dpo3->dpoi_next_node; vnet_buffer(b1)->ip.adj_index[VLIB_TX] = dpo1->dpoi_index; vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index; vnet_buffer(b2)->ip.adj_index[VLIB_TX] = dpo2->dpoi_index; vnet_buffer(b3)->ip.adj_index[VLIB_TX] = dpo3->dpoi_index; if (interface_count) { vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, thread_index, adj0->rewrite_header.sw_if_index, 1, vlib_buffer_length_in_chain (vm, b0)); vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, thread_index, adj1->rewrite_header.sw_if_index, 1, vlib_buffer_length_in_chain (vm, b1)); vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, thread_index, adj2->rewrite_header.sw_if_index, 1, vlib_buffer_length_in_chain (vm, b2)); vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, thread_index, adj3->rewrite_header.sw_if_index, 1, vlib_buffer_length_in_chain (vm, b3)); } if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); tr->ai = adj_index0; } if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED)) { adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node, b1, sizeof (*tr)); tr->ai = adj_index1; } if (PREDICT_FALSE(b2->flags & VLIB_BUFFER_IS_TRACED)) { adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node, b2, sizeof (*tr)); tr->ai = adj_index2; } if (PREDICT_FALSE(b3->flags & VLIB_BUFFER_IS_TRACED)) { adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node, b3, sizeof (*tr)); tr->ai = adj_index3; } vlib_validate_buffer_enqueue_x4 (vm, node, next_index, to_next, n_left_to_next, bi0, bi1, bi2, bi3, next0, next1, next2, next3); } while (n_left_from > 0 && n_left_to_next > 0) { u32 bi0, adj_index0, next0; const ip_adjacency_t * adj0; const dpo_id_t *dpo0; vlib_buffer_t * b0; bi0 = from[0]; to_next[0] = bi0; from += 1; to_next += 1; n_left_from -= 1; n_left_to_next -= 1; b0 = vlib_get_buffer(vm, bi0); /* Follow the DPO on which the midchain is stacked */ adj_index0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX]; adj0 = adj_get(adj_index0); dpo0 = &adj0->sub_type.midchain.next_dpo; next0 = dpo0->dpoi_next_node; vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index; if (interface_count) { vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, thread_index, adj0->rewrite_header.sw_if_index, 1, vlib_buffer_length_in_chain (vm, b0)); } if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); tr->ai = adj_index0; } vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi0, next0); } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } return frame->n_vectors; }
clib_bihash_kv_16_8_t kv; } stn_ip46_punt_trace_t; static u8 * format_stn_rule (u8 * s, va_list * args) { stn_rule_t *r = va_arg (*args, stn_rule_t *); stn_main_t *stn = &stn_main; u32 indent = format_get_indent (s); u32 node_index = ip46_address_is_ip4(&r->address)?stn_ip4_punt.index:stn_ip6_punt.index; vlib_node_t *next_node = vlib_get_next_node(vlib_get_main(), node_index, r->next_node_index); s = format (s, "rule_index: %d\n", r - stn->rules); s = format (s, "%Uaddress: %U\n", format_white_space, indent, format_ip46_address, &r->address, IP46_TYPE_ANY); s = format (s, "%Uiface: %U (%d)\n", format_white_space, indent, format_vnet_sw_if_index_name, vnet_get_main(), r->sw_if_index, r->sw_if_index); s = format (s, "%Unext_node: %s (%d)", format_white_space, indent, next_node->name, next_node->index); return s; } static_always_inline u8 * format_stn_ip46_punt_trace (u8 * s, va_list * args, u8 is_ipv4) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); stn_ip46_punt_trace_t *t = va_arg (*args, stn_ip46_punt_trace_t *); u32 indent = format_get_indent (s); s = format (s, "dst_address: %U\n", format_ip46_address,
return 0; } /**********************************/ /* SRv6 LocalSID format functions */ /* * Prints nicely the parameters of a localsid * Example: print "Table 5" */ u8 * format_srv6_am_localsid (u8 * s, va_list * args) { srv6_am_localsid_t *ls_mem = va_arg (*args, void *); vnet_main_t *vnm = vnet_get_main (); return (format (s, "Next-hop:\t%U\n" "\tOutgoing iface: %U\n" "\tIncoming iface: %U", format_ip6_address, &ls_mem->nh_addr.ip6, format_vnet_sw_if_index_name, vnm, ls_mem->sw_if_index_out, format_vnet_sw_if_index_name, vnm, ls_mem->sw_if_index_in)); } /* * Process the parameters of a localsid * Example: process from: * sr localsid address cafe::1 behavior new_srv6_localsid 5 * everything from behavior on... so in this case 'new_srv6_localsid 5'
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; }
static clib_error_t * virtual_ip_cmd_fn_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { unformat_input_t _line_input, * line_input = &_line_input; vnet_main_t * vnm = vnet_get_main(); ip4_main_t * im = &ip4_main; ip_lookup_main_t * lm = &im->lookup_main; ip4_address_t ip_addr, next_hop; u8 mac_addr[6]; mac_addr_t *mac_addrs = 0; u32 sw_if_index; u32 i, f; /* Get a line of input. */ if (! unformat_user (input, unformat_line_input, line_input)) return 0; if (!unformat(line_input, "%U %U", unformat_ip4_address, &ip_addr, unformat_vnet_sw_interface, vnm, &sw_if_index)) goto barf; while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { if (unformat (line_input, "mac %U", unformat_ethernet_address, &mac_addr)) { mac_addr_t *ma; vec_add2 (mac_addrs, ma, 1); clib_memcpy(ma, mac_addr, sizeof (mac_addr)); } else { barf: return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); } } if (vec_len (mac_addrs) == 0) goto barf; /* Create / delete special interface route /32's */ next_hop.as_u32 = 0; for (i = 0; i < vec_len(mac_addrs); i++) { ip_adjacency_t adj; u32 adj_index; adj.lookup_next_index = IP_LOOKUP_NEXT_REWRITE; vnet_rewrite_for_sw_interface (vnm, VNET_L3_PACKET_TYPE_IP4, sw_if_index, ip4_rewrite_node.index, &mac_addrs[i], /* destination address */ &adj.rewrite_header, sizeof (adj.rewrite_data)); ip_add_adjacency (lm, &adj, 1 /* one adj */, &adj_index); f = (i + 1 < vec_len(mac_addrs)) ? IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP : 0; ip4_add_del_route_next_hop (im, IP4_ROUTE_FLAG_ADD | f, &ip_addr, 32 /* insert /32's */, &next_hop, sw_if_index, 1 /* weight */, adj_index, (u32)~0 /* explicit fib index */); } vec_free (mac_addrs); return 0; }