aboutsummaryrefslogtreecommitdiffstats
BranchCommit messageAuthorAge
masterhttp_static: fix memory hss_session using after be freedXiaomingJiang10 hours
stable/2406prom: test_prom fixMatus Fabian8 weeks
stable/2402build: update octeon-roc checksum to updated versionDave Wallace8 weeks
stable/2310sr: use correct reply to sr_policy_add_v2Vratko Polak5 months
stable/2306vpp-swan: fix configuration of policiesGabriel Oginski12 months
stable/2302vlib: reset stop_timer_handle on expired processesMatthew Smith12 months
stable/2210nat: fix nat44 vrf handlersDaniel Béreš18 months
stable/2206misc: VPP 22.06.1 Release NotesDave Wallace19 months
stable/2106ipsec: fix AES CBC IV generation (CVE-2022-46397)Benoît Ganne20 months
stable/2101ipsec: fix AES CBC IV generation (CVE-2022-46397)Benoît Ganne20 months
stable/2009ipsec: fix AES CBC IV generation (CVE-2022-46397)Benoît Ganne20 months
stable/2005ipsec: fix AES CBC IV generation (CVE-2022-46397)Benoît Ganne20 months
stable/2001ipsec: fix AES CBC IV generation (CVE-2022-46397)Benoît Ganne20 months
stable/1904ipsec: fix AES CBC IV generation (CVE-2022-46397)Benoît Ganne20 months
stable/1908ipsec: fix AES CBC IV generation (CVE-2022-46397)Benoît Ganne20 months
stable/2110ipsec: fix AES CBC IV generation (CVE-2022-46397)Benoît Ganne20 months
stable/2202ipsec: fix AES CBC IV generation (CVE-2022-46397)Benoît Ganne20 months
stable/1901vlib: address vlib_error_t scaling issueSteven Luong5 years
stable/1807Clean up multi-thread barrier-sync hold-down timerDave Barach5 years
stable/1810mp_safe SW_INTERFACE_DUMP, SW_INTERFACE_DETAILS, SW_INTERFACE_TAG_ADD_DEL,Steven Luong5 years
stable/1804fix packets redirect ineffective on af-packet interfacechenxiang6 years
stable/1801fix issue with missing sample_main in sample pluginDamjan Marion6 years
stable/1710l2-flood: fix restore vnet buffer's flags in the replication routineSteve Shin7 years
stable/1707Add replicate DPO header to export list for VPPSBNeale Ranns7 years
stable/1704VPP debug image with worker threads hit assert on adding IP route with traffi...Neale Ranns7 years
stable/1701Fix pretty-printing in "api trace custom-dump" (VPP-683)Andrew Yourtchenko7 years
stable/1609Vhost: Add thread sync while receiving vhost messagePierre Pfister8 years
stable/1606Fix generate-deb-changelog to handle YY.MM releaseEd Warnicke8 years
stable/testWhitespace probe for CIEd Warnicke8 years
 
TagDownloadAuthorAge
v24.06commit 6e8b350a01...Andrew Yourtchenko3 months
v24.06-rc2commit 55457075d9...Andrew Yourtchenko3 months
v24.06-rc1commit b3304b2b76...Andrew Yourtchenko4 months
v24.10-rc0commit 71e0902454...Andrew Yourtchenko4 months
v24.02commit 455960759b...Andrew Yourtchenko7 months
v24.02-rc2commit 8cbf84dce0...Andrew Yourtchenko7 months
v24.02-rc1commit 3a56e86a73...Andrew Yourtchenko8 months
v24.06-rc0commit 6fb2b3dc72...Andrew Yourtchenko8 months
v23.10commit 7c4027fa5e...Andrew Yourtchenko11 months
v23.10-rc2commit 015a6f7f17...Andrew Yourtchenko11 months
v23.10-rc1commit 14df6fc1ea...Andrew Yourtchenko12 months
v24.02-rc0commit 7419bede7a...Andrew Yourtchenko12 months
v23.06commit 493b8990d1...Andrew Yourtchenko15 months
v23.06-rc2commit 5e6bc730ef...Andrew Yourtchenko15 months
v23.06-rc1commit b60a6477eb...Andrew Yourtchenko16 months
v23.10-rc0commit a7dd04d73b...Andrew Yourtchenko16 months
v23.02commit 5516fc0f3b...Andrew Yourtchenko19 months
v22.10.1commit 57302fe52f...Dave Wallace19 months
v22.06.1commit 1513b381d8...Dave Wallace19 months
v23.02-rc2commit be1b844214...Andrew Yourtchenko20 months
v23.02-rc1commit 42b5a8767c...Andrew Yourtchenko20 months
v23.06-rc0commit 2ebb95228f...Andrew Yourtchenko20 months
v22.10commit 07e0c05e69...Andrew Yourtchenko23 months
v22.10-rc2commit 61bae8a54d...Andrew Yourtchenko23 months
v22.10-rc1commit f845abb5dd...Andrew Yourtchenko2 years
v23.02-rc0commit a2a7a4031b...Andrew Yourtchenko2 years
v22.06commit 0d352a97c5...Andrew Yourtchenko2 years
v22.06-rc2commit ea4bcec987...Andrew Yourtchenko2 years
v22.06-rc1commit 211fa4748c...Andrew Yourtchenko2 years
v22.10-rc0commit e0301eeb7b...Andrew Yourtchenko2 years
v22.02commit 7911f29c51...Andrew Yourtchenko3 years
v22.02-rc2commit 9d2db2eb2e...Andrew Yourtchenko3 years
v22.02-rc1commit 93e5bea2d3...Andrew Yourtchenko3 years
v22.06-rc0commit 017a676654...Andrew Yourtchenko3 years
v21.10.1commit 0385458a56...Andrew Yourtchenko3 years
v21.10commit 0e0384cde9...Andrew Yourtchenko3 years
v21.10-rc2commit c1931b2f09...Andrew Yourtchenko3 years
v21.10-rc1commit fd9d936b3c...Andrew Yourtchenko3 years
v22.02-rc0commit 192c55f2e7...Andrew Yourtchenko
/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * node.c: srp packet processing
 *
 * Copyright (c) 2011 Eliot Dresselhaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <vlib/vlib.h>
#include <vnet/ip/ip_packet.h>	/* for ip_csum_fold */
#include <vnet/srp/srp.h>

srp_main_t srp_main;

typedef struct {
  u8 packet_data[32];
} srp_input_trace_t;

static u8 * format_srp_input_trace (u8 * s, va_list * va)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
  srp_input_trace_t * t = va_arg (*va, srp_input_trace_t *);

  s = format (s, "%U", format_srp_header, t->packet_data);

  return s;
}

typedef enum {
  SRP_INPUT_NEXT_ERROR,
  SRP_INPUT_NEXT_ETHERNET_INPUT,
  SRP_INPUT_NEXT_CONTROL,
  SRP_INPUT_N_NEXT,
} srp_input_next_t;

typedef struct {
  u8 next_index;
  u8 buffer_advance;
  u16 error;
} srp_input_disposition_t;

static srp_input_disposition_t srp_input_disposition_by_mode[8] = {
  [SRP_MODE_reserved0] = {
    .next_index = SRP_INPUT_NEXT_ERROR,
    .error = SRP_ERROR_UNKNOWN_MODE,
  },
  [SRP_MODE_reserved1] = {
    .next_index = SRP_INPUT_NEXT_ERROR,
    .error = SRP_ERROR_UNKNOWN_MODE,
  },
  [SRP_MODE_reserved2] = {
    .next_index = SRP_INPUT_NEXT_ERROR,
    .error = SRP_ERROR_UNKNOWN_MODE,
  },
  [SRP_MODE_reserved3] = {
    .next_index = SRP_INPUT_NEXT_ERROR,
    .error = SRP_ERROR_UNKNOWN_MODE,
  },
  [SRP_MODE_keep_alive] = {
    .next_index = SRP_INPUT_NEXT_ERROR,
    .error = SRP_ERROR_KEEP_ALIVE_DROPPED,
  },
  [SRP_MODE_data] = {
    .next_index = SRP_INPUT_NEXT_ETHERNET_INPUT,
    .buffer_advance = sizeof (srp_header_t),
  },
  [SRP_MODE_control_pass_to_host] = {
    .next_index = SRP_INPUT_NEXT_CONTROL,
  },
  [SRP_MODE_control_locally_buffered_for_host] = {
    .next_index = SRP_INPUT_NEXT_CONTROL,
  },
};

static uword
srp_input (vlib_main_tcommit b163bbb748...
Andrew Yourtchenko4 years
v19.08.2commit ec9ce338f0...Andrew Yourtchenko4 years
v20.01commit fce396738f...Andrew Yourtchenko5 years
v20.01-rc2commit 29acfa2ad5...Andrew Yourtchenko5 years
v20.01-rc1commit c7fe31cfff...Andrew Yourtchenko5 years
v20.05-rc0commit 8ad070e102...Andrew Yourtchenko5 years
v19.04.4-rc0commit dfec10d137...Dave Wallace5 years
v19.04.3commit bdb89b9897...Dave Wallace5 years
v19.08.1commit f4dcae4164...Andrew Yourtchenko5 years
v19.08commit 1c586de48c...Andrew Yourtchenko5 years
v19.08-rc2commit 2f51729bb3...Andrew Yourtchenko5 years
v19.08-rc1commit 23526f78a8...Andrew Yourtchenko5 years
v20.01-rc0commit e41fd65381...Andrew Yourtchenko5 years
v19.04.2commit d95a226047...Dave Wallace5 years
v19.01.3commit bef25c30a1...Andrew Yourtchenko5 years
v19.04.2-rc0commit e4a0f9fdc0...Dave Wallace5 years
v19.01.3-rc0commit 6af8243814...Dave Wallace5 years
v19.04.1commit 1662c9cd23...Dave Wallace5 years
v19.01.2commit fa63602fcb...Andrew Yourtchenko5 years
v19.01.2-rc0commit 67a3e2d130...Dave Wallace5 years
v19.04.1-rc0commit 873b9ed405...Dave Wallace5 years
v19.04commit 3d18a191aa...Dave Wallace5 years
v19.04-rc2commit 0d7332e43f...Dave Wallace5 years
v19.08-rc0commit 40fd1f3dfd...Dave Wallace5 years
v19.04-rc1commit e29b8228a2...Dave Wallace5 years
v19.01.1commit cbd68cb711...Dave Wallace6 years
v19.01commit 67d9475ae3...Andrew Yourtchenko6 years
v19.01-rc2commit 0cb68778ec...Andrew Yourtchenko6 years
v19.01-rc1commit 3e2bc759f4...Damjan Marion6 years
v19.04-rc0commit ef080e1f9b...Andrew Yourtchenko6 years
v18.10commit 3a9a6f72d1...Marco Varlese6 years
v18.10-rc2commit b3aff922ff...Marco Varlese6 years
v19.01-rc0commit 4f611176e9...Marco Varlese6 years
v18.10-rc1commit 90395743d3...Marco Varlese6 years
v18.07.1commit 55fbdb9941...Ed Warnicke6 years
v18.07commit db6d6b3058...Ed Warnicke6 years
v18.07-rc2commit c16a23c596...Ed Warnicke6 years
v18.10-rc0commit 0e6f4d6af4...Ed Warnicke6 years
v18.07-rc0commit 3e21eba4d2...Ed Warnicke6 years
v18.07-rc1commit e400a6d1a5...Ed Warnicke6 years
v18.01.2commit 540b31ac8f...Dave Wallace6 years
v18.04commit ac2b7363f4...Chris Luke6 years
v18.04-rc2commit 18744ee680...Chris Luke6 years
v18.04-rc1commit 7ace56b9d8...Chris Luke6 years
v18.01.1commit f13bac295d...Dave Wallace7 years
v18.01commit 9d21268d0a...Dave Wallace7 years
v18.01-rc2commit bbdfeaebf2...Dave Wallace7 years
v18.01-rc1commit 8c2bacde4f...Dave Wallace7 years
v18.04-rc0commit a3a6ec63d3...Dave Wallace7 years
v17.10commit 116af2170e...Florin Coras7 years
v17.10-rc2commit cf6c343710...Florin Coras7 years
v18.01-rc0commit 75a17ecddc...Florin Coras7 years
v17.10-rc1commit 7ea28045aa...Florin Coras7 years
v17.07.01commit 839fa732c1...Neale Ranns7 years
v17.07commit f4f635e7c0...Neale Ranns7 years
v17.07-rc2commit 01d2b4b13a...Neale Ranns7 years
v17.10-rc0commit cdc74273df...Neale Ranns7 years
v17.07-rc1commit ea89b8cf66...Neale Ranns7 years
v17.04.2commit fc69a97116...Ole Troan7 years
v17.04.1commit 7d68ec6134...Ole Troan7 years
v17.04commit 511ee63cbb...Ole Troan7 years
v17.04-rc2commit 92bcecfdcc...Ole Troan7 years
v17.07-rc0commit 87edd671d7...Ole Troan8 years
v17.04-rc1commit cb92fc6edc...Ole Troan8 years
v17.01.1commit 8099e90346...Damjan Marion8 years
v17.01commit cd111b2228...Damjan Marion8 years
v17.01-rc2commit 235c64f067...Damjan Marion8 years
v17.04-rc0commit 2e70d8b31d...Damjan Marion8 years
v17.01-rc1commit 436b319354...Damjan Marion8 years
v17.01-rc0commit 931be3aca2...Ed Warnicke8 years
v16.09commit 21bc8624f5...Keith Burns (alagalah)8 years
v16.09-rc2commit 08377f8ff7...Keith Burns (alagalah)8 years
v16.12-rc0commit 694265d4f1...Dave Barach8 years
v16.09-rc1commit dbc6e3f0bb...Dave Barach8 years
v16.06commit 693f4358de...Ed Warnicke8 years
v16.06-rc3commit cf6511560e...Dave Barach8 years
v16.06-rc2commit b98a3a87a9...Dave Barach8 years
v16.09-rc0commit 862623da6e...Ed Warnicke8 years
v16.06-rc1commit 826d4f7b1f...Ed Warnicke8 years
v1.0.0commit cb9cadad57...Ed Warnicke9 years
rror_node->errors[error0]; next0 = 0; 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; } static vlib_node_registration_t srp_control_input_node = { .function = srp_control_input, .name = "srp-control", /* Takes a vector of packets. */ .vector_size = sizeof (u32), .n_next_nodes = 1, .next_nodes = { [0] = "error-drop", }, .format_buffer = format_srp_header_with_length, .format_trace = format_srp_input_trace, .unformat_buffer = unformat_srp_header, }; static u8 * format_srp_ips_request_type (u8 * s, va_list * args) { u32 x = va_arg (*args, u32); char * t = 0; switch (x) { #define _(f,n) case SRP_IPS_REQUEST_##f: t = #f; break; foreach_srp_ips_request_type #undef _ default: return format (s, "unknown 0x%x", x); } return format (s, "%U", format_c_identifier, t); } static u8 * format_srp_ips_status (u8 * s, va_list * args) { u32 x = va_arg (*args, u32); char * t = 0; switch (x) { #define _(f,n) case SRP_IPS_STATUS_##f: t = #f; break; foreach_srp_ips_status #undef _ default: return format (s, "unknown 0x%x", x); } return format (s, "%U", format_c_identifier, t); } static u8 * format_srp_ips_state (u8 * s, va_list * args) { u32 x = va_arg (*args, u32); char * t = 0; switch (x) { #define _(f) case SRP_IPS_STATE_##f: t = #f; break; foreach_srp_ips_state #undef _ default: return format (s, "unknown 0x%x", x); } return format (s, "%U", format_c_identifier, t); } static u8 * format_srp_ring (u8 * s, va_list * args) { u32 ring = va_arg (*args, u32); return format (s, "%s", ring == SRP_RING_INNER ? "inner" : "outer"); } static u8 * format_srp_ips_header (u8 * s, va_list * args) { srp_ips_header_t * h = va_arg (*args, srp_ips_header_t *); s = format (s, "%U, %U, %U, %s-path", format_srp_ips_request_type, h->request_type, format_ethernet_address, h->originator_address, format_srp_ips_status, h->status, h->is_long_path ? "long" : "short"); return s; } static u8 * format_srp_interface (u8 * s, va_list * args) { srp_interface_t * si = va_arg (*args, srp_interface_t *); srp_interface_ring_t * ir; s = format (s, "address %U, IPS state %U", format_ethernet_address, si->my_address, format_srp_ips_state, si->current_ips_state); for (ir = si->rings; ir < si->rings + SRP_N_RING; ir++) if (ir->rx_neighbor_address_valid) s = format (s, ", %U neighbor %U", format_srp_ring, ir->ring, format_ethernet_address, ir->rx_neighbor_address); return s; } u8 * format_srp_device (u8 * s, va_list * args) { u32 hw_if_index = va_arg (*args, u32); CLIB_UNUSED (int verbose) = va_arg (*args, int); vnet_main_t * vnm = vnet_get_main(); srp_main_t * sm = &srp_main; vnet_hw_interface_t * hi = vnet_get_hw_interface (vnm, hw_if_index); srp_interface_t * si = pool_elt_at_index (sm->interface_pool, hi->hw_instance); return format (s, "%U", format_srp_interface, si); } always_inline srp_interface_t * srp_get_interface (u32 sw_if_index, srp_ring_type_t * ring) { vnet_main_t * vnm = vnet_get_main(); srp_main_t * sm = &srp_main; vnet_hw_interface_t * hi = vnet_get_sup_hw_interface (vnm, sw_if_index); srp_interface_t * si; ASSERT (hi->hw_class_index == srp_hw_interface_class.index); si = pool_elt_at_index (sm->interface_pool, hi->hw_instance); ASSERT (si->rings[SRP_RING_INNER].hw_if_index == hi->hw_if_index || si->rings[SRP_RING_OUTER].hw_if_index == hi->hw_if_index); if (ring) *ring = (hi->hw_if_index == si->rings[SRP_RING_INNER].hw_if_index ? SRP_RING_INNER : SRP_RING_OUTER); return si; } static void init_ips_packet (srp_interface_t * si, srp_ring_type_t tx_ring, srp_ips_header_t * i) { memset (i, 0, sizeof (i[0])); i->srp.ttl = 1; i->srp.is_inner_ring = tx_ring; i->srp.priority = 7; i->srp.mode = SRP_MODE_control_locally_buffered_for_host; srp_header_compute_parity (&i->srp); clib_memcpy (&i->ethernet.src_address, &si->my_address, sizeof (si->my_address)); i->ethernet.type = clib_host_to_net_u16 (ETHERNET_TYPE_SRP_CONTROL); /* Checksum will be filled in later. */ i->control.version = 0; i->control.type = SRP_CONTROL_PACKET_TYPE_ips; i->control.ttl = 255; clib_memcpy (&i->originator_address, &si->my_address, sizeof (si->my_address)); } static void tx_ips_packet (srp_interface_t * si, srp_ring_type_t tx_ring, srp_ips_header_t * i) { srp_main_t * sm = &srp_main; vnet_main_t * vnm = vnet_get_main(); vlib_main_t * vm = sm->vlib_main; vnet_hw_interface_t * hi = vnet_get_hw_interface (vnm, si->rings[tx_ring].hw_if_index); vlib_frame_t * f; vlib_buffer_t * b; u32 * to_next, bi; if (! vnet_sw_interface_is_admin_up (vnm, hi->sw_if_index)) return; if (hi->hw_class_index != srp_hw_interface_class.index) return; i->control.checksum = ~ip_csum_fold (ip_incremental_checksum (0, &i->control, sizeof (i[0]) - STRUCT_OFFSET_OF (srp_ips_header_t, control))); bi = vlib_buffer_add_data (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX, /* buffer to append to */ ~0, i, sizeof (i[0])); /* FIXME trace. */ if (0) clib_warning ("%U %U", format_vnet_sw_if_index_name, vnm, hi->sw_if_index, format_srp_ips_header, i); b = vlib_get_buffer (vm, bi); vnet_buffer (b)->sw_if_index[VLIB_RX] = vnet_buffer (b)->sw_if_index[VLIB_TX] = hi->sw_if_index; f = vlib_get_frame_to_node (vm, hi->output_node_index); to_next = vlib_frame_vector_args (f); to_next[0] = bi; f->n_vectors = 1; vlib_put_frame_to_node (vm, hi->output_node_index, f); } static int requests_switch (srp_ips_request_type_t r) { static u8 t[16] = { [SRP_IPS_REQUEST_forced_switch] = 1, [SRP_IPS_REQUEST_manual_switch] = 1, [SRP_IPS_REQUEST_signal_fail] = 1, [SRP_IPS_REQUEST_signal_degrade] = 1, }; return (int) r < ARRAY_LEN (t) ? t[r] : 0; } /* Called when an IPS control packet is received on given interface. */ void srp_ips_rx_packet (u32 sw_if_index, srp_ips_header_t * h) { vnet_main_t * vnm = vnet_get_main(); vlib_main_t * vm = srp_main.vlib_main; srp_ring_type_t rx_ring; srp_interface_t * si = srp_get_interface (sw_if_index, &rx_ring); srp_interface_ring_t * ir = &si->rings[rx_ring]; /* FIXME trace. */ if (0) clib_warning ("%U %U %U", format_time_interval, "h:m:s:u", vlib_time_now (vm), format_vnet_sw_if_index_name, vnm, sw_if_index, format_srp_ips_header, h); /* Ignore self-generated IPS packets. */ if (! memcmp (h->originator_address, si->my_address, sizeof (h->originator_address))) goto done; /* Learn neighbor address from short path messages. */ if (! h->is_long_path) { if (ir->rx_neighbor_address_valid && memcmp (ir->rx_neighbor_address, h->originator_address, sizeof (ir->rx_neighbor_address))) { ASSERT (0); } ir->rx_neighbor_address_valid = 1; clib_memcpy (ir->rx_neighbor_address, h->originator_address, sizeof (ir->rx_neighbor_address)); } switch (si->current_ips_state) { case SRP_IPS_STATE_idle: /* Received {REQ,NEIGHBOR,W,S} in idle state: wrap. */ if (requests_switch (h->request_type) && ! h->is_long_path && h->status == SRP_IPS_STATUS_wrapped) { srp_ips_header_t to_tx[2]; si->current_ips_state = SRP_IPS_STATE_wrapped; si->hw_wrap_function (si->rings[SRP_SIDE_A].hw_if_index, /* enable_wrap */ 1); si->hw_wrap_function (si->rings[SRP_SIDE_B].hw_if_index, /* enable_wrap */ 1); init_ips_packet (si, rx_ring ^ 0, &to_tx[0]); to_tx[0].request_type = SRP_IPS_REQUEST_idle; to_tx[0].status = SRP_IPS_STATUS_wrapped; to_tx[0].is_long_path = 0; tx_ips_packet (si, rx_ring ^ 0, &to_tx[0]); init_ips_packet (si, rx_ring ^ 1, &to_tx[1]); to_tx[1].request_type = h->request_type; to_tx[1].status = SRP_IPS_STATUS_wrapped; to_tx[1].is_long_path = 1; tx_ips_packet (si, rx_ring ^ 1, &to_tx[1]); } break; case SRP_IPS_STATE_wrapped: if (! h->is_long_path && h->request_type == SRP_IPS_REQUEST_idle && h->status == SRP_IPS_STATUS_idle) { si->current_ips_state = SRP_IPS_STATE_idle; si->hw_wrap_function (si->rings[SRP_SIDE_A].hw_if_index, /* enable_wrap */ 0); si->hw_wrap_function (si->rings[SRP_SIDE_B].hw_if_index, /* enable_wrap */ 0); } break; case SRP_IPS_STATE_pass_thru: /* FIXME */ break; default: abort (); break; } done: ; } /* Preform local IPS request on given interface. */ void srp_ips_local_request (u32 sw_if_index, srp_ips_request_type_t request) { vnet_main_t * vnm = vnet_get_main(); srp_main_t * sm = &srp_main; srp_ring_type_t rx_ring; srp_interface_t * si = srp_get_interface (sw_if_index, &rx_ring); srp_interface_ring_t * ir = &si->rings[rx_ring]; if (request == SRP_IPS_REQUEST_wait_to_restore) { if (si->current_ips_state != SRP_IPS_STATE_wrapped) return; if (! ir->waiting_to_restore) { ir->wait_to_restore_start_time = vlib_time_now (sm->vlib_main); ir->waiting_to_restore = 1; } } else { /* FIXME handle local signal fail. */ ir->wait_to_restore_start_time = 0; ir->waiting_to_restore = 0; } /* FIXME trace. */ if (0) clib_warning ("%U %U", format_vnet_sw_if_index_name, vnm, sw_if_index, format_srp_ips_request_type, request); } static void maybe_send_ips_message (srp_interface_t * si) { srp_main_t * sm = &srp_main; srp_ips_header_t to_tx[2]; srp_ring_type_t rx_ring = SRP_RING_OUTER; srp_interface_ring_t * r0 = &si->rings[rx_ring ^ 0]; srp_interface_ring_t * r1 = &si->rings[rx_ring ^ 1]; f64 now = vlib_time_now (sm->vlib_main); if (! si->ips_process_enable) return; if (si->current_ips_state == SRP_IPS_STATE_wrapped && r0->waiting_to_restore && r1->waiting_to_restore && now >= r0->wait_to_restore_start_time + si->config.wait_to_restore_idle_delay && now >= r1->wait_to_restore_start_time + si->config.wait_to_restore_idle_delay) { si->current_ips_state = SRP_IPS_STATE_idle; r0->waiting_to_restore = r1->waiting_to_restore = 0; r0->wait_to_restore_start_time = r1->wait_to_restore_start_time = 0; } if (si->current_ips_state != SRP_IPS_STATE_idle) return; init_ips_packet (si, rx_ring ^ 0, &to_tx[0]); init_ips_packet (si, rx_ring ^ 1, &to_tx[1]); if (si->current_ips_state == SRP_IPS_STATE_idle) { to_tx[0].request_type = to_tx[1].request_type = SRP_IPS_REQUEST_idle; to_tx[0].status = to_tx[1].status = SRP_IPS_STATUS_idle; to_tx[0].is_long_path = to_tx[1].is_long_path = 0; } else if (si->current_ips_state == SRP_IPS_STATE_wrapped) { to_tx[0].request_type = (si->rings[rx_ring ^ 0].waiting_to_restore ? SRP_IPS_REQUEST_wait_to_restore : SRP_IPS_REQUEST_signal_fail); to_tx[1].request_type = (si->rings[rx_ring ^ 1].waiting_to_restore ? SRP_IPS_REQUEST_wait_to_restore : SRP_IPS_REQUEST_signal_fail); to_tx[0].status = to_tx[1].status = SRP_IPS_STATUS_wrapped; to_tx[0].is_long_path = 0; to_tx[1].is_long_path = 1; } tx_ips_packet (si, rx_ring ^ 0, &to_tx[0]); tx_ips_packet (si, rx_ring ^ 1, &to_tx[1]); } static uword srp_ips_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) { srp_main_t * sm = &srp_main; srp_interface_t * si; while (1) { pool_foreach (si, sm->interface_pool, ({ maybe_send_ips_message (si); })); vlib_process_suspend (vm, 1.0); } return 0; } vlib_node_registration_t srp_ips_process_node = { .function = srp_ips_process, .type = VLIB_NODE_TYPE_PROCESS, .name = "srp-ips-process", .state = VLIB_NODE_STATE_DISABLED, }; static clib_error_t * srp_init (vlib_main_t * vm) { srp_main_t * sm = &srp_main; sm->default_data_ttl = 255; sm->vlib_main = vm; vlib_register_node (vm, &srp_ips_process_node); vlib_register_node (vm, &srp_input_node); vlib_register_node (vm, &srp_control_input_node); srp_setup_node (vm, srp_input_node.index); return 0; } VLIB_INIT_FUNCTION (srp_init);