X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fsrv6-as%2Fas.c;h=99e68511f32c74e7b42ad4730b262a16ab219b02;hb=eeb5fb3a5;hp=b8ce68c981a62da73076db32e206a0ae49e97c4a;hpb=9f30c1708f81985f1c4b22b4770e14f41d916485;p=vpp.git diff --git a/src/plugins/srv6-as/as.c b/src/plugins/srv6-as/as.c index b8ce68c981a..99e68511f32 100644 --- a/src/plugins/srv6-as/as.c +++ b/src/plugins/srv6-as/as.c @@ -36,6 +36,7 @@ unsigned char def_str[] = unsigned char params_str[] = "nh oif iif src next [next ...]"; +srv6_as_main_t srv6_as_main; static inline u8 * prepare_rewrite (ip6_address_t src_addr, ip6_address_t * sid_list, @@ -63,7 +64,7 @@ prepare_rewrite (ip6_address_t src_addr, ip6_address_t * sid_list, iph->src_address = src_addr; iph->dst_address = sid_list[0]; iph->payload_length = sr_hdr_len; - iph->hop_limit = IPv6_DEFAULT_HOP_LIMIT; + iph->hop_limit = sr_get_hop_limit (); if (num_sids > 1) { @@ -76,13 +77,13 @@ prepare_rewrite (ip6_address_t src_addr, ip6_address_t * sid_list, srh->length = sr_hdr_len / 8 - 1; srh->type = ROUTING_HEADER_TYPE_SR; srh->segments_left = num_sids - 1; - srh->first_segment = num_sids - 1; + srh->last_entry = num_sids - 1; srh->flags = 0x00; - srh->reserved = 0x00; + srh->tag = 0x0000; /* Fill segment list */ ip6_address_t *this_address; - ip6_address_t *addrp = srh->segments + srh->first_segment; + ip6_address_t *addrp = srh->segments + srh->last_entry; vec_foreach (this_address, sid_list) { *addrp = *this_address; @@ -121,18 +122,21 @@ srv6_as_localsid_creation_fn (ip6_sr_localsid_t * localsid) /* Retrieve the adjacency corresponding to the (OIF, next_hop) */ adj_index_t nh_adj_index = ADJ_INDEX_INVALID; - if (ls_mem->ip_version == DA_IP4) - nh_adj_index = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4, - VNET_LINK_IP4, &ls_mem->nh_addr, - ls_mem->sw_if_index_out); - else if (ls_mem->ip_version == DA_IP6) - 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) + if (ls_mem->inner_type != AS_TYPE_L2) { - free_ls_mem (ls_mem); - return SID_CREATE_INVALID_ADJ_INDEX; + if (ls_mem->inner_type == AS_TYPE_IP4) + nh_adj_index = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4, + VNET_LINK_IP4, &ls_mem->nh_addr, + ls_mem->sw_if_index_out); + else if (ls_mem->inner_type == AS_TYPE_IP6) + 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) + { + free_ls_mem (ls_mem); + return SID_CREATE_INVALID_ADJ_INDEX; + } } ls_mem->nh_adj = nh_adj_index; @@ -159,7 +163,37 @@ srv6_as_localsid_creation_fn (ip6_sr_localsid_t * localsid) return SID_CREATE_INVALID_IFACE_TYPE; } - if (ls_mem->ip_version == DA_IP4) + if (ls_mem->inner_type == AS_TYPE_L2) + { + /* Enable End.AS2 rewrite node for this interface */ + int ret = + vnet_feature_enable_disable ("device-input", "srv6-as2-rewrite", + ls_mem->sw_if_index_in, 1, 0, 0); + if (ret != 0) + { + free_ls_mem (ls_mem); + return SID_CREATE_IFACE_FEATURE_ERROR; + } + + /* Set interface in promiscuous mode */ + vnet_main_t *vnm = vnet_get_main (); + ethernet_set_flags (vnm, ls_mem->sw_if_index_in, + ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); + + /* Prepare rewrite string */ + ls_mem->rewrite = prepare_rewrite (ls_mem->src_addr, ls_mem->sid_list, + IP_PROTOCOL_IP6_NONXT); + + /* Associate local SID index to this interface (resize vector if needed) */ + if (ls_mem->sw_if_index_in >= vec_len (sm->sw_iface_localsid2)) + { + vec_resize (sm->sw_iface_localsid2, + (pool_len (sm->vnet_main->interface_main.sw_interfaces) + - vec_len (sm->sw_iface_localsid2))); + } + sm->sw_iface_localsid2[ls_mem->sw_if_index_in] = localsid_index; + } + else if (ls_mem->inner_type == AS_TYPE_IP4) { /* Enable End.AS4 rewrite node for this interface */ int ret = @@ -185,7 +219,7 @@ srv6_as_localsid_creation_fn (ip6_sr_localsid_t * localsid) } sm->sw_iface_localsid4[ls_mem->sw_if_index_in] = localsid_index; } - else if (ls_mem->ip_version == DA_IP6) + else if (ls_mem->inner_type == AS_TYPE_IP6) { /* Enable End.AS6 rewrite node for this interface */ int ret = @@ -212,6 +246,18 @@ srv6_as_localsid_creation_fn (ip6_sr_localsid_t * localsid) sm->sw_iface_localsid6[ls_mem->sw_if_index_in] = localsid_index; } + /* Step 3: Initialize rewrite counters */ + srv6_as_localsid_t **ls_p; + pool_get (sm->sids, ls_p); + *ls_p = ls_mem; + ls_mem->index = ls_p - sm->sids; + + vlib_validate_combined_counter (&(sm->valid_counters), ls_mem->index); + vlib_validate_combined_counter (&(sm->invalid_counters), ls_mem->index); + + vlib_zero_combined_counter (&(sm->valid_counters), ls_mem->index); + vlib_zero_combined_counter (&(sm->invalid_counters), ls_mem->index); + return 0; } @@ -221,7 +267,23 @@ srv6_as_localsid_removal_fn (ip6_sr_localsid_t * localsid) srv6_as_main_t *sm = &srv6_as_main; srv6_as_localsid_t *ls_mem = localsid->plugin_mem; - if (ls_mem->ip_version == DA_IP4) + if (ls_mem->inner_type == AS_TYPE_L2) + { + /* Disable End.AS2 rewrite node for this interface */ + int ret; + ret = vnet_feature_enable_disable ("device-input", "srv6-as2-rewrite", + ls_mem->sw_if_index_in, 0, 0, 0); + if (ret != 0) + return -1; + + /* Disable promiscuous mode on the interface */ + vnet_main_t *vnm = vnet_get_main (); + ethernet_set_flags (vnm, ls_mem->sw_if_index_in, 0); + + /* Remove local SID index from interface table */ + sm->sw_iface_localsid2[ls_mem->sw_if_index_in] = ~(u32) 0; + } + else if (ls_mem->inner_type == AS_TYPE_IP4) { /* Disable End.AS4 rewrite node for this interface */ int ret; @@ -233,7 +295,7 @@ srv6_as_localsid_removal_fn (ip6_sr_localsid_t * localsid) /* Remove local SID index from interface table */ sm->sw_iface_localsid4[ls_mem->sw_if_index_in] = ~(u32) 0; } - else if (ls_mem->ip_version == DA_IP6) + else if (ls_mem->inner_type == AS_TYPE_IP6) { /* Disable End.AS6 rewrite node for this interface */ int ret; @@ -250,6 +312,9 @@ srv6_as_localsid_removal_fn (ip6_sr_localsid_t * localsid) /* Unlock (OIF, NHOP) adjacency (from sr_localsid.c:103) */ adj_unlock (ls_mem->nh_adj); + /* Delete SID entry */ + pool_put (sm->sids, pool_elt_at_index (sm->sids, ls_mem->index)); + /* Clean up local SID memory */ free_ls_mem (ls_mem); @@ -268,21 +333,22 @@ format_srv6_as_localsid (u8 * s, va_list * args) srv6_as_localsid_t *ls_mem = va_arg (*args, void *); vnet_main_t *vnm = vnet_get_main (); + srv6_as_main_t *sm = &srv6_as_main; - if (ls_mem->ip_version == DA_IP4) + if (ls_mem->inner_type == AS_TYPE_IP4) { s = - format (s, "Next-hop:\t%U\n", format_ip4_address, + format (s, "Next-hop:\t%U\n\t", format_ip4_address, &ls_mem->nh_addr.ip4); } - else + else if (ls_mem->inner_type == AS_TYPE_IP6) { s = - format (s, "Next-hop:\t%U\n", format_ip6_address, + format (s, "Next-hop:\t%U\n\t", format_ip6_address, &ls_mem->nh_addr.ip6); } - s = format (s, "\tOutgoing iface:\t%U\n", format_vnet_sw_if_index_name, vnm, + s = format (s, "Outgoing iface:\t%U\n", format_vnet_sw_if_index_name, vnm, ls_mem->sw_if_index_out); s = format (s, "\tIncoming iface:\t%U\n", format_vnet_sw_if_index_name, vnm, ls_mem->sw_if_index_in); @@ -295,7 +361,18 @@ format_srv6_as_localsid (u8 * s, va_list * args) { s = format (s, "%U, ", format_ip6_address, addr); } - s = format (s, "\b\b > "); + s = format (s, "\b\b >\n"); + + vlib_counter_t valid, invalid; + vlib_get_combined_counter (&(sm->valid_counters), ls_mem->index, &valid); + vlib_get_combined_counter (&(sm->invalid_counters), ls_mem->index, + &invalid); + s = + format (s, "\tGood rewrite traffic: \t[%Ld packets : %Ld bytes]\n", + valid.packets, valid.bytes); + s = + format (s, "\tBad rewrite traffic: \t[%Ld packets : %Ld bytes]\n", + invalid.packets, invalid.bytes); return s; } @@ -315,7 +392,7 @@ unformat_srv6_as_localsid (unformat_input_t * input, va_list * args) vnet_main_t *vnm = vnet_get_main (); - u8 ip_version = 0; + u8 inner_type = AS_TYPE_L2; ip46_address_t nh_addr; u32 sw_if_index_out; u32 sw_if_index_in; @@ -338,14 +415,14 @@ unformat_srv6_as_localsid (unformat_input_t * input, va_list * args) unformat_ip4_address, &nh_addr.ip4)) { - ip_version = DA_IP4; + inner_type = AS_TYPE_IP4; params |= PARAM_AS_NH; } if (!(params & PARAM_AS_NH) && unformat (input, "nh %U", unformat_ip6_address, &nh_addr.ip6)) { - ip_version = DA_IP6; + inner_type = AS_TYPE_IP6; params |= PARAM_AS_NH; } else if (!(params & PARAM_AS_OIF) && unformat (input, "oif %U", @@ -377,7 +454,7 @@ unformat_srv6_as_localsid (unformat_input_t * input, va_list * args) } /* Make sure that all parameters are supplied */ - u8 params_chk = (PARAM_AS_NH | PARAM_AS_OIF | PARAM_AS_IIF | PARAM_AS_SRC); + u8 params_chk = (PARAM_AS_OIF | PARAM_AS_IIF | PARAM_AS_SRC); if ((params & params_chk) != params_chk || sid_list == NULL) { vec_free (sid_list); @@ -386,14 +463,14 @@ unformat_srv6_as_localsid (unformat_input_t * input, va_list * args) /* Allocate and initialize memory block for local SID parameters */ ls_mem = clib_mem_alloc_aligned_at_offset (sizeof *ls_mem, 0, 0, 1); - memset (ls_mem, 0, sizeof *ls_mem); + clib_memset (ls_mem, 0, sizeof *ls_mem); *plugin_mem_p = ls_mem; /* Set local SID parameters */ - ls_mem->ip_version = ip_version; - if (ip_version == DA_IP4) + ls_mem->inner_type = inner_type; + if (inner_type == AS_TYPE_IP4) ls_mem->nh_addr.ip4 = nh_addr.ip4; - else + else if (inner_type == AS_TYPE_IP6) ls_mem->nh_addr.ip6 = nh_addr.ip6; ls_mem->sw_if_index_out = sw_if_index_out; ls_mem->sw_if_index_in = sw_if_index_in; @@ -472,6 +549,13 @@ srv6_as_init (vlib_main_t * vm) } /* *INDENT-OFF* */ +VNET_FEATURE_INIT (srv6_as2_rewrite, static) = +{ + .arc_name = "device-input", + .node_name = "srv6-as2-rewrite", + .runs_before = VNET_FEATURES ("ethernet-input"), +}; + VNET_FEATURE_INIT (srv6_as4_rewrite, static) = { .arc_name = "ip4-unicast", @@ -490,7 +574,7 @@ VLIB_INIT_FUNCTION (srv6_as_init); VLIB_PLUGIN_REGISTER () = { .version = VPP_BUILD_VER, - .description = "Static SRv6 proxy", + .description = "Static Segment Routing for IPv6 (SRv6) Proxy", }; /* *INDENT-ON* */