static clib_error_t * join_socket_read_ready (unix_file_t * uf) { mc_socket_main_t *msm = (mc_socket_main_t *)uf->private_data; mc_main_t * mcm = &msm->mc_main; vlib_main_t * vm = mcm->vlib_main; mc_multicast_socket_t * ms = &msm->multicast_sockets[MC_TRANSPORT_JOIN]; clib_error_t * error; u32 bi; error = recvmsg_helper (msm, ms->socket, /* rx_addr */ 0, &bi, /* drop_message */ 0); if (! error) { vlib_buffer_t * b = vlib_get_buffer (vm, bi); mc_msg_join_or_leave_request_t * mp = vlib_buffer_get_current (b); switch (clib_host_to_net_u32 (mp->type)) { case MC_MSG_TYPE_join_or_leave_request: msg_handler (mcm, bi, /* handler_frees_buffer */ 0, mc_msg_join_or_leave_request_handler); break; case MC_MSG_TYPE_join_reply: msg_handler (mcm, bi, /* handler_frees_buffer */ 0, mc_msg_join_reply_handler); break; default: ASSERT (0); break; } } return error; }
/* vmxnet3 delete API */ static int api_vmxnet3_delete (vat_main_t * vam) { unformat_input_t *i = vam->input; vl_api_vmxnet3_delete_t *mp; u32 sw_if_index = 0; u8 index_defined = 0; int ret; while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) { if (unformat (i, "sw_if_index %u", &sw_if_index)) index_defined = 1; else { clib_warning ("unknown input '%U'", format_unformat_error, i); return -99; } } if (!index_defined) { errmsg ("missing sw_if_index\n"); return -99; } M (VMXNET3_DELETE, mp); mp->sw_if_index = clib_host_to_net_u32 (sw_if_index); S (mp); W (ret); return ret; }
static clib_error_t * to_relay_socket_read_ready (unix_file_t * uf) { mc_socket_main_t *msm = (mc_socket_main_t *)uf->private_data; mc_main_t *mcm = &msm->mc_main; vlib_main_t * vm = msm->mc_main.vlib_main; mc_multicast_socket_t * ms_to_relay = &msm->multicast_sockets[MC_TRANSPORT_USER_REQUEST_TO_RELAY]; mc_multicast_socket_t * ms_from_relay = &msm->multicast_sockets[MC_TRANSPORT_USER_REQUEST_FROM_RELAY]; clib_error_t * error; u32 bi; u32 is_master = mcm->relay_state == MC_RELAY_STATE_MASTER; /* Not the ordering master? Turf the msg */ error = recvmsg_helper (msm, ms_to_relay->socket, /* rx_addr */ 0, &bi, /* drop_message */ ! is_master); /* If we are the master, number and rebroadcast the msg. */ if (! error && is_master) { vlib_buffer_t * b = vlib_get_buffer (vm, bi); mc_msg_user_request_t * mp = vlib_buffer_get_current (b); mp->global_sequence = clib_host_to_net_u32 (mcm->relay_global_sequence); mcm->relay_global_sequence++; error = sendmsg_helper (msm, ms_from_relay->socket, &ms_from_relay->tx_addr, bi); vlib_buffer_free_one (vm, bi); } return error; }
static void send_udp_encap_details (const udp_encap_t * ue, vl_api_registration_t * reg, u32 context) { vl_api_udp_encap_details_t *mp; mp = vl_msg_api_alloc (sizeof (*mp)); clib_memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = ntohs (VL_API_UDP_ENCAP_DETAILS); mp->context = context; if (FIB_PROTOCOL_IP4 == ue->ue_ip_proto) { clib_memcpy (&mp->udp_encap.src_ip.un.ip4, &ue->ue_hdrs.ip4.ue_ip4.src_address, 4); clib_memcpy (&mp->udp_encap.dst_ip.un.ip4, &ue->ue_hdrs.ip4.ue_ip4.dst_address, 4); mp->udp_encap.dst_ip.af = clib_host_to_net_u32 (ADDRESS_IP4); mp->udp_encap.src_ip.af = clib_host_to_net_u32 (ADDRESS_IP4); /* ports aren't byte swapped because they are stored in network * byte order */ mp->udp_encap.src_port = ue->ue_hdrs.ip4.ue_udp.src_port; mp->udp_encap.dst_port = ue->ue_hdrs.ip4.ue_udp.dst_port; } else { clib_memcpy (&mp->udp_encap.src_ip.un.ip6, &ue->ue_hdrs.ip6.ue_ip6.src_address, 16); clib_memcpy (&mp->udp_encap.dst_ip.un.ip6, &ue->ue_hdrs.ip6.ue_ip6.dst_address, 16); mp->udp_encap.dst_ip.af = clib_host_to_net_u32 (ADDRESS_IP6); mp->udp_encap.src_ip.af = clib_host_to_net_u32 (ADDRESS_IP6); /* ports aren't byte swapped because they are stored in network * byte order */ mp->udp_encap.src_port = ue->ue_hdrs.ip6.ue_udp.src_port; mp->udp_encap.dst_port = ue->ue_hdrs.ip6.ue_udp.dst_port; } mp->udp_encap.table_id = htonl (fib_table_get_table_id (ue->ue_fib_index, ue->ue_ip_proto)); mp->udp_encap.id = htonl (ue - udp_encap_pool); vl_api_send_msg (reg, (u8 *) mp); }
void ip_mprefix_encode (const mfib_prefix_t * in, vl_api_mprefix_t * out) { out->af = (FIB_PROTOCOL_IP6 == in->fp_proto ? ADDRESS_IP6 : ADDRESS_IP4); out->af = clib_host_to_net_u32 (out->af); out->grp_address_length = clib_host_to_net_u16 (in->fp_len); ip_address_union_encode (&in->fp_grp_addr, out->af, &out->grp_address); ip_address_union_encode (&in->fp_src_addr, out->af, &out->src_address); }
/* vmxnet3 create API */ static int api_vmxnet3_create (vat_main_t * vam) { unformat_input_t *i = vam->input; vl_api_vmxnet3_create_t *mp; vmxnet3_create_if_args_t args; int ret; u32 x[4]; clib_memset (&args, 0, sizeof (vmxnet3_create_if_args_t)); while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) { if (unformat (i, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3])) { args.addr.domain = x[0]; args.addr.bus = x[1]; args.addr.slot = x[2]; args.addr.function = x[3]; } else if (unformat (i, "elog")) args.enable_elog = 1; else if (unformat (i, "bind")) args.bind = 1; else if (unformat (i, "rx-queue-size %u", &args.rxq_size)) ; else if (unformat (i, "tx-queue-size %u", &args.txq_size)) ; else if (unformat (i, "num-tx-queues %u", &args.txq_num)) ; else if (unformat (i, "num-rx-queues %u", &args.rxq_num)) ; else { clib_warning ("unknown input '%U'", format_unformat_error, i); return -99; } } M (VMXNET3_CREATE, mp); mp->pci_addr = clib_host_to_net_u32 (args.addr.as_u32); mp->enable_elog = clib_host_to_net_u16 (args.enable_elog); mp->rxq_size = clib_host_to_net_u16 (args.rxq_size); mp->txq_size = clib_host_to_net_u16 (args.txq_size); mp->txq_num = clib_host_to_net_u16 (args.txq_num); mp->rxq_num = clib_host_to_net_u16 (args.rxq_num); mp->bind = args.bind; S (mp); W (ret); return ret; }
/** * @brief API message custom-dump function * @param mp vl_api_flowprobe_tx_interface_add_del_t * mp the api message * @param handle void * print function handle * @returns u8 * output string */ static void *vl_api_flowprobe_tx_interface_add_del_t_print (vl_api_flowprobe_tx_interface_add_del_t * mp, void *handle) { u8 *s; s = format (0, "SCRIPT: flowprobe_tx_interface_add_del "); s = format (s, "sw_if_index %d is_add %d which %d ", clib_host_to_net_u32 (mp->sw_if_index), (int) mp->is_add, (int) mp->which); FINISH; }
/* * ip6_sixrd */ static uword ip6_sixrd (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) { u32 n_left_from, *from, next_index, *to_next, n_left_to_next; vlib_node_runtime_t *error_node = vlib_node_get_runtime(vm, ip6_sixrd_node.index); u32 encap = 0; from = vlib_frame_vector_args(frame); n_left_from = frame->n_vectors; next_index = node->cached_next_index; while (n_left_from > 0) { vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) { u32 pi0; vlib_buffer_t *p0; sixrd_domain_t *d0; u8 error0 = SIXRD_ERROR_NONE; ip6_header_t *ip60; ip4_header_t *ip4h0; u32 next0 = IP6_SIXRD_NEXT_IP4_LOOKUP; u32 sixrd_domain_index0 = ~0; pi0 = to_next[0] = from[0]; from += 1; n_left_from -= 1; to_next +=1; n_left_to_next -= 1; p0 = vlib_get_buffer(vm, pi0); ip60 = vlib_buffer_get_current(p0); // p0->current_length = clib_net_to_host_u16(ip40->length); d0 = ip6_sixrd_get_domain(vnet_buffer(p0)->ip.adj_index[VLIB_TX], &sixrd_domain_index0); ASSERT(d0); /* SIXRD calc */ u64 dal60 = clib_net_to_host_u64(ip60->dst_address.as_u64[0]); u32 da40 = sixrd_get_addr(d0, dal60); u16 len = clib_net_to_host_u16(ip60->payload_length) + 60; if (da40 == 0) error0 = SIXRD_ERROR_UNKNOWN; /* construct ipv4 header */ vlib_buffer_advance(p0, - (sizeof(ip4_header_t))); ip4h0 = vlib_buffer_get_current(p0); vnet_buffer(p0)->sw_if_index[VLIB_TX] = (u32)~0; ip4h0->ip_version_and_header_length = 0x45; ip4h0->tos = 0; ip4h0->length = clib_host_to_net_u16(len); ip4h0->fragment_id = 0; ip4h0->flags_and_fragment_offset = 0; ip4h0->ttl = 0x40; ip4h0->protocol = IP_PROTOCOL_IPV6; ip4h0->src_address = d0->ip4_src; ip4h0->dst_address.as_u32 = clib_host_to_net_u32(da40); ip4h0->checksum = ip4_header_checksum(ip4h0); next0 = error0 == SIXRD_ERROR_NONE ? IP6_SIXRD_NEXT_IP4_LOOKUP : IP6_SIXRD_NEXT_DROP; if (PREDICT_FALSE(p0->flags & VLIB_BUFFER_IS_TRACED)) { sixrd_trace_t *tr = vlib_add_trace(vm, node, p0, sizeof(*tr)); tr->sixrd_domain_index = sixrd_domain_index0; } p0->error = error_node->errors[error0]; if (PREDICT_TRUE(error0 == SIXRD_ERROR_NONE)) encap++; vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, pi0, next0); } vlib_put_next_frame(vm, node, next_index, n_left_to_next); } vlib_node_increment_counter(vm, ip6_sixrd_node.index, SIXRD_ERROR_ENCAPSULATED, encap); return frame->n_vectors; }
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; }
always_inline uword bier_imp_dpo_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame, fib_protocol_t fproto, bier_hdr_proto_id_t bproto) { u32 n_left_from, next_index, * from, * to_next; from = vlib_frame_vector_args (from_frame); n_left_from = from_frame->n_vectors; next_index = node->cached_next_index; while (n_left_from > 0) { u32 n_left_to_next; vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) { vlib_buffer_t * b0; bier_imp_t *bimp0; bier_hdr_t *hdr0; u32 bi0, bii0; u32 next0; 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); bii0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX]; bimp0 = bier_imp_get(bii0); if (FIB_PROTOCOL_IP4 == fproto) { /* * decrement the TTL on ingress to the BIER domain */ ip4_header_t * ip0 = vlib_buffer_get_current(b0); u32 checksum0; checksum0 = ip0->checksum + clib_host_to_net_u16 (0x0100); checksum0 += checksum0 >= 0xffff; ip0->checksum = checksum0; ip0->ttl -= 1; /* * calculate an entropy */ if (0 == vnet_buffer(b0)->ip.flow_hash) { vnet_buffer(b0)->ip.flow_hash = ip4_compute_flow_hash (ip0, IP_FLOW_HASH_DEFAULT); } } if (FIB_PROTOCOL_IP6 == fproto) { /* * decrement the TTL on ingress to the BIER domain */ ip6_header_t * ip0 = vlib_buffer_get_current(b0); ip0->hop_limit -= 1; /* * calculate an entropy */ if (0 == vnet_buffer(b0)->ip.flow_hash) { vnet_buffer(b0)->ip.flow_hash = ip6_compute_flow_hash (ip0, IP_FLOW_HASH_DEFAULT); } } /* Paint the BIER header */ vlib_buffer_advance(b0, -(sizeof(bier_hdr_t) + bier_hdr_len_id_to_num_bytes(bimp0->bi_tbl.bti_hdr_len))); hdr0 = vlib_buffer_get_current(b0); /* RPF check */ if (PREDICT_FALSE(BIER_RX_ITF == vnet_buffer(b0)->ip.adj_index[VLIB_RX])) { next0 = 0; } else { clib_memcpy_fast(hdr0, &bimp0->bi_hdr, (sizeof(bier_hdr_t) + bier_hdr_len_id_to_num_bytes(bimp0->bi_tbl.bti_hdr_len))); /* * Fixup the entropy and protocol, both of which have a * zero value post the paint job */ hdr0->bh_oam_dscp_proto |= clib_host_to_net_u16(bproto << BIER_HDR_PROTO_FIELD_SHIFT); hdr0->bh_first_word |= clib_host_to_net_u32((vnet_buffer(b0)->ip.flow_hash & BIER_HDR_ENTROPY_FIELD_MASK) << BIER_HDR_ENTROPY_FIELD_SHIFT); /* * use TTL 64 for the post enacp MPLS label/BIFT-ID * this we be decremeted in bier_output node. */ vnet_buffer(b0)->mpls.ttl = 65; /* next node */ next0 = bimp0->bi_dpo[fproto].dpoi_next_node; vnet_buffer(b0)->ip.adj_index[VLIB_TX] = bimp0->bi_dpo[fproto].dpoi_index; } if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { bier_imp_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); tr->imp = bii0; tr->hdr = *hdr0; } 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 from_frame->n_vectors; }
inline void swap_ip_dst_emip_src(ipv4_header *ip, icmp_em_ip_info *icmp_info, cnat_main_db_entry_t *db, u16 vrf) { icmp_v4_t *icmp; ipv4_header *em_ip; u16 *em_port; u32 old_ip; u16 old_port; u16 old_ip_checksum; /* * declear variable */ CNAT_UPDATE_L3_CHECKSUM_DECLARE CNAT_UPDATE_ICMP_ERR_CHECKSUM_DECLARE /* * fix inner layer ip & l4 checksum */ em_ip = icmp_info->em_ip; em_port = icmp_info->em_port; CNAT_UPDATE_L3_CHECKSUM(((u16)(db->out2in_key.k.ipv4)), ((u16)(db->out2in_key.k.ipv4 >> 16)), (clib_net_to_host_u16(em_ip->checksum)), ((u16)(db->in2out_key.k.ipv4)), ((u16)(db->in2out_key.k.ipv4 >> 16))) old_ip = clib_net_to_host_u32(em_ip->src_addr); old_port = clib_net_to_host_u16(*em_port); old_ip_checksum = clib_net_to_host_u16(em_ip->checksum); em_ip->src_addr = clib_host_to_net_u32(db->in2out_key.k.ipv4); em_ip->checksum = clib_host_to_net_u16(new_l3_c); *em_port = clib_host_to_net_u16(db->in2out_key.k.port); /* * fix outter layer ip & icmp checksum */ icmp = icmp_info->icmp; CNAT_UPDATE_ICMP_ERR_CHECKSUM(((u16)(old_ip & 0xFFFF)), ((u16)(old_ip >> 16)), (old_port), (old_ip_checksum), (clib_net_to_host_u16(icmp->checksum)), ((u16)(db->in2out_key.k.ipv4 & 0xffff)), ((u16)(db->in2out_key.k.ipv4 >> 16)), ((u16)(db->in2out_key.k.port)), ((u16)(new_l3_c))) icmp->checksum = clib_host_to_net_u16(new_icmp_c); old_ip = clib_net_to_host_u32(ip->dest_addr); ip->dest_addr = clib_host_to_net_u32(db->in2out_key.k.ipv4); CNAT_UPDATE_L3_CHECKSUM(((u16)(old_ip & 0xFFFF)), ((u16)(old_ip >> 16)), (clib_net_to_host_u16(ip->checksum)), ((u16)(db->in2out_key.k.ipv4)), ((u16)(db->in2out_key.k.ipv4 >> 16))) ip->checksum = clib_host_to_net_u16(new_l3_c); #if 0 if(is_static_dest_nat_enabled(vrf) == CNAT_SUCCESS) { /* * fix inner layer ip & l4 checksum */ em_snat_ip = icmp_info->em_ip; em_snat_port = icmp_info->em_port; old_ip = spp_net_to_host_byte_order_32(&(em_snat_ip->dest_addr)); old_port = spp_net_to_host_byte_order_16(em_snat_port); old_ip_checksum = spp_net_to_host_byte_order_16(&(em_snat_ip->checksum)); direction = 1; if(cnat_static_dest_db_get_translation(em_snat_ip->dest_addr, &postmap_ip, vrf, direction) == CNAT_SUCCESS) { old_postmap_ip = spp_net_to_host_byte_order_32(&postmap_ip); CNAT_UPDATE_L3_CHECKSUM(((u16)(old_ip)), ((u16)(old_ip >> 16)), (spp_net_to_host_byte_order_16(&(em_snat_ip->checksum))), ((u16)(old_postmap_ip)), ((u16)(old_postmap_ip >> 16))) em_snat_ip->dest_addr = postmap_ip; em_snat_ip->checksum = spp_host_to_net_byte_order_16(new_l3_c); /* * fix outter layer ip & icmp checksum */ icmp = icmp_info->icmp; CNAT_UPDATE_ICMP_ERR_CHECKSUM(((u16)(old_ip & 0xFFFF)), ((u16)(old_ip >> 16)), (old_port), (old_ip_checksum), (spp_net_to_host_byte_order_16(&(icmp->checksum))), ((u16)(old_postmap_ip & 0xffff)), ((u16)(old_postmap_ip >> 16)), ((u16)(old_port)), ((u16)(new_l3_c))) icmp->checksum = spp_host_to_net_byte_order_16(new_icmp_c); }
static u32 add_del_ip_tunnel (vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u32 * tun_index_res) { lisp_gpe_main_t * lgm = &lisp_gpe_main; lisp_gpe_tunnel_t *t = 0; uword * p; int rv; lisp_gpe_tunnel_key_t key; /* prepare tunnel key */ memset(&key, 0, sizeof(key)); ip_prefix_copy(&key.eid, &gid_address_ippref(&a->deid)); ip_address_copy(&key.dst_loc, &a->dlocator); key.iid = clib_host_to_net_u32 (a->vni); p = mhash_get (&lgm->lisp_gpe_tunnel_by_key, &key); if (a->is_add) { /* adding a tunnel: tunnel must not already exist */ if (p) return VNET_API_ERROR_INVALID_VALUE; if (a->decap_next_index >= LISP_GPE_INPUT_N_NEXT) return VNET_API_ERROR_INVALID_DECAP_NEXT; pool_get_aligned (lgm->tunnels, t, CLIB_CACHE_LINE_BYTES); memset (t, 0, sizeof (*t)); /* copy from arg structure */ #define _(x) t->x = a->x; foreach_copy_field; #undef _ ip_address_copy(&t->src, &a->slocator); ip_address_copy(&t->dst, &a->dlocator); /* if vni is non-default */ if (a->vni) { t->flags = LISP_GPE_FLAGS_I; t->vni = a->vni; } t->flags |= LISP_GPE_FLAGS_P; t->next_protocol = ip_prefix_version(&key.eid) == IP4 ? LISP_GPE_NEXT_PROTO_IP4 : LISP_GPE_NEXT_PROTO_IP6; rv = lisp_gpe_rewrite (t); if (rv) { pool_put(lgm->tunnels, t); return rv; } mhash_set(&lgm->lisp_gpe_tunnel_by_key, &key, t - lgm->tunnels, 0); /* return tunnel index */ if (tun_index_res) tun_index_res[0] = t - lgm->tunnels; } else { /* deleting a tunnel: tunnel must exist */ if (!p) { clib_warning("Tunnel for eid %U doesn't exist!", format_gid_address, &a->deid); return VNET_API_ERROR_NO_SUCH_ENTRY; } t = pool_elt_at_index(lgm->tunnels, p[0]); mhash_unset(&lgm->lisp_gpe_tunnel_by_key, &key, 0); vec_free(t->rewrite); pool_put(lgm->tunnels, t); } return 0; }
static int lisp_gpe_rewrite (lisp_gpe_tunnel_t * t) { u8 *rw = 0; lisp_gpe_header_t * lisp0; int len; if (ip_addr_version(&t->src) == IP4) { ip4_header_t * ip0; ip4_udp_lisp_gpe_header_t * h0; len = sizeof(*h0); vec_validate_aligned(rw, len - 1, CLIB_CACHE_LINE_BYTES); h0 = (ip4_udp_lisp_gpe_header_t *) rw; /* Fixed portion of the (outer) ip4 header */ ip0 = &h0->ip4; ip0->ip_version_and_header_length = 0x45; ip0->ttl = 254; ip0->protocol = IP_PROTOCOL_UDP; /* we fix up the ip4 header length and checksum after-the-fact */ ip_address_copy_addr(&ip0->src_address, &t->src); ip_address_copy_addr(&ip0->dst_address, &t->dst); ip0->checksum = ip4_header_checksum (ip0); /* UDP header, randomize src port on something, maybe? */ h0->udp.src_port = clib_host_to_net_u16 (4341); h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_lisp_gpe); /* LISP-gpe header */ lisp0 = &h0->lisp; } else { ip6_header_t * ip0; ip6_udp_lisp_gpe_header_t * h0; len = sizeof(*h0); vec_validate_aligned(rw, len - 1, CLIB_CACHE_LINE_BYTES); h0 = (ip6_udp_lisp_gpe_header_t *) rw; /* Fixed portion of the (outer) ip6 header */ ip0 = &h0->ip6; ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32 (0x6 << 28); ip0->hop_limit = 254; ip0->protocol = IP_PROTOCOL_UDP; /* we fix up the ip6 header length after-the-fact */ ip_address_copy_addr(&ip0->src_address, &t->src); ip_address_copy_addr(&ip0->dst_address, &t->dst); /* UDP header, randomize src port on something, maybe? */ h0->udp.src_port = clib_host_to_net_u16 (4341); h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_lisp_gpe); /* LISP-gpe header */ lisp0 = &h0->lisp; } lisp0->flags = t->flags; lisp0->ver_res = t->ver_res; lisp0->res = t->res; lisp0->next_protocol = t->next_protocol; lisp0->iid = clib_host_to_net_u32 (t->vni); t->rewrite = rw; return 0; }
/** * @brief Create an IPFIX template packet rewrite string * @param frm flow_report_main_t * * @param fr flow_report_t * * @param collector_address ip4_address_t * the IPFIX collector address * @param src_address ip4_address_t * the source address we should use * @param collector_port u16 the collector port we should use, host byte order * @returns u8 * vector containing the indicated IPFIX template packet */ static inline u8 * flowprobe_template_rewrite_inline (flow_report_main_t * frm, flow_report_t * fr, ip4_address_t * collector_address, ip4_address_t * src_address, u16 collector_port, flowprobe_variant_t which) { ip4_header_t *ip; udp_header_t *udp; ipfix_message_header_t *h; ipfix_set_header_t *s; ipfix_template_header_t *t; ipfix_field_specifier_t *f; ipfix_field_specifier_t *first_field; u8 *rewrite = 0; ip4_ipfix_template_packet_t *tp; u32 field_count = 0; flow_report_stream_t *stream; flowprobe_main_t *fm = &flowprobe_main; flowprobe_record_t flags = fr->opaque.as_uword; bool collect_ip4 = false, collect_ip6 = false; stream = &frm->streams[fr->stream_index]; if (flags & FLOW_RECORD_L3) { collect_ip4 = which == FLOW_VARIANT_L2_IP4 || which == FLOW_VARIANT_IP4; collect_ip6 = which == FLOW_VARIANT_L2_IP6 || which == FLOW_VARIANT_IP6; if (which == FLOW_VARIANT_L2_IP4) flags |= FLOW_RECORD_L2_IP4; if (which == FLOW_VARIANT_L2_IP6) flags |= FLOW_RECORD_L2_IP6; } field_count += flowprobe_template_common_field_count (); if (flags & FLOW_RECORD_L2) field_count += flowprobe_template_l2_field_count (); if (collect_ip4) field_count += flowprobe_template_ip4_field_count (); if (collect_ip6) field_count += flowprobe_template_ip6_field_count (); if (flags & FLOW_RECORD_L4) field_count += flowprobe_template_l4_field_count (); /* allocate rewrite space */ vec_validate_aligned (rewrite, sizeof (ip4_ipfix_template_packet_t) + field_count * sizeof (ipfix_field_specifier_t) - 1, CLIB_CACHE_LINE_BYTES); tp = (ip4_ipfix_template_packet_t *) rewrite; ip = (ip4_header_t *) & tp->ip4; udp = (udp_header_t *) (ip + 1); h = (ipfix_message_header_t *) (udp + 1); s = (ipfix_set_header_t *) (h + 1); t = (ipfix_template_header_t *) (s + 1); first_field = f = (ipfix_field_specifier_t *) (t + 1); ip->ip_version_and_header_length = 0x45; ip->ttl = 254; ip->protocol = IP_PROTOCOL_UDP; ip->src_address.as_u32 = src_address->as_u32; ip->dst_address.as_u32 = collector_address->as_u32; udp->src_port = clib_host_to_net_u16 (stream->src_port); udp->dst_port = clib_host_to_net_u16 (collector_port); udp->length = clib_host_to_net_u16 (vec_len (rewrite) - sizeof (*ip)); /* FIXUP: message header export_time */ /* FIXUP: message header sequence_number */ h->domain_id = clib_host_to_net_u32 (stream->domain_id); /* Add TLVs to the template */ f = flowprobe_template_common_fields (f); if (flags & FLOW_RECORD_L2) f = flowprobe_template_l2_fields (f); if (collect_ip4) f = flowprobe_template_ip4_fields (f); if (collect_ip6) f = flowprobe_template_ip6_fields (f); if (flags & FLOW_RECORD_L4) f = flowprobe_template_l4_fields (f); /* Back to the template packet... */ ip = (ip4_header_t *) & tp->ip4; udp = (udp_header_t *) (ip + 1); ASSERT (f - first_field); /* Field count in this template */ t->id_count = ipfix_id_count (fr->template_id, f - first_field); fm->template_size[flags] = (u8 *) f - (u8 *) s; /* set length in octets */ s->set_id_length = ipfix_set_id_length (2 /* set_id */ , (u8 *) f - (u8 *) s); /* message length in octets */ h->version_length = version_length ((u8 *) f - (u8 *) h); ip->length = clib_host_to_net_u16 ((u8 *) f - (u8 *) ip); ip->checksum = ip4_header_checksum (ip); return rewrite; }
((u16)(db->out2in_key.k.ipv4 >> 16)), (db->out2in_key.k.port)) /* #define UDP_PACKET_DEBUG 1 */ // Temporary debugs which will be suppressed later #ifdef UDP_PACKET_DEBUG if (PREDICT_FALSE(udp_inside_packet_dump_enable)) { printf("\nIn2Out UDP packet before translation"); print_udp_pkt(ip); } #endif //set ip header ip->src_addr = clib_host_to_net_u32(db->out2in_key.k.ipv4); ip->checksum = clib_host_to_net_u16(new_l3_c); u16 frag_offset = clib_net_to_host_u16(ip->frag_flags_offset); if(PREDICT_FALSE(frag_offset & IP_FRAG_OFFSET_MASK)) { return; /* No need to update UDP fields */ } //set udp header udp->src_port = clib_host_to_net_u16(db->out2in_key.k.port); /* * No easy way to avoid this if check except by using