summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohn Lo <loj@cisco.com>2017-03-10 17:15:22 -0500
committerDave Barach <openvpp@barachs.net>2017-03-13 14:35:01 +0000
commit1904c47d5f79f8e9dcc6c9ae2043e7d6be8bd6d8 (patch)
tree29e82e2299067be4779a91fde37393ba6cb357d9 /src
parent59dda065bb92d1588824483ed5e7cf9adb228d3a (diff)
Add MAC address check in ethernet-input node if interface in L3 mode
Interface can be in promiscuous mode if more than one of its sub- interface is in L2 mode. In promiscuous mode, L3 interface need to verify DMAC of packet to match that of the interface and drop if not. This check was done on sub-interface only and now also added to main interface path. Fix incorrect MAC addresses in the flow-per-pkt plugin test, which caused it to fail. Fix MAC address usage in BFD tests. Change-Id: I12a17ec05c7ab298ad10d400c90d082c97eca521 Signed-off-by: John Lo <loj@cisco.com> Signed-off-by: Klement Sekera <ksekera@cisco.com>
Diffstat (limited to 'src')
-rwxr-xr-xsrc/vnet/ethernet/node.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/vnet/ethernet/node.c b/src/vnet/ethernet/node.c
index 6d57da31708..b699e381f91 100755
--- a/src/vnet/ethernet/node.c
+++ b/src/vnet/ethernet/node.c
@@ -294,6 +294,7 @@ ethernet_input_inline (vlib_main_t * vm,
u32 cpu_index = os_get_cpu_number ();
u32 cached_sw_if_index = ~0;
u32 cached_is_l2 = 0; /* shut up gcc */
+ vnet_hw_interface_t *hi = NULL; /* used for main interface only */
if (variant != ETHERNET_INPUT_VARIANT_ETHERNET)
error_node = vlib_node_get_runtime (vm, ethernet_input_node.index);
@@ -386,11 +387,12 @@ ethernet_input_inline (vlib_main_t * vm,
if (PREDICT_FALSE (sw_if_index0 != sw_if_index1))
goto slowpath;
+ /* Now sw_if_index0 == sw_if_index1 */
if (PREDICT_FALSE (cached_sw_if_index != sw_if_index0))
{
cached_sw_if_index = sw_if_index0;
- hi0 = vnet_get_sup_hw_interface (vnm, sw_if_index0);
- intf0 = vec_elt_at_index (em->main_intfs, hi0->hw_if_index);
+ hi = vnet_get_sup_hw_interface (vnm, sw_if_index0);
+ intf0 = vec_elt_at_index (em->main_intfs, hi->hw_if_index);
subint0 = &intf0->untagged_subint;
cached_is_l2 = is_l20 = subint0->flags & SUBINT_CONFIG_L2;
}
@@ -409,6 +411,12 @@ ethernet_input_inline (vlib_main_t * vm,
}
else
{
+ if (!ethernet_address_cast (e0->dst_address) &&
+ !eth_mac_equal ((u8 *) e0, hi->hw_address))
+ error0 = ETHERNET_ERROR_L3_MAC_MISMATCH;
+ if (!ethernet_address_cast (e1->dst_address) &&
+ !eth_mac_equal ((u8 *) e1, hi->hw_address))
+ error1 = ETHERNET_ERROR_L3_MAC_MISMATCH;
determine_next_node (em, variant, 0, type0, b0,
&error0, &next0);
vlib_buffer_advance (b0, sizeof (ethernet_header_t));
@@ -540,10 +548,10 @@ ethernet_input_inline (vlib_main_t * vm,
determine_next_node (em, variant, is_l21, type1, b1, &error1,
&next1);
+ ship_it01:
b0->error = error_node->errors[error0];
b1->error = error_node->errors[error1];
- ship_it01:
// verify speculative enqueue
vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
n_left_to_next, bi0, bi1, next0,
@@ -603,8 +611,8 @@ ethernet_input_inline (vlib_main_t * vm,
if (PREDICT_FALSE (cached_sw_if_index != sw_if_index0))
{
cached_sw_if_index = sw_if_index0;
- hi0 = vnet_get_sup_hw_interface (vnm, sw_if_index0);
- intf0 = vec_elt_at_index (em->main_intfs, hi0->hw_if_index);
+ hi = vnet_get_sup_hw_interface (vnm, sw_if_index0);
+ intf0 = vec_elt_at_index (em->main_intfs, hi->hw_if_index);
subint0 = &intf0->untagged_subint;
cached_is_l2 = is_l20 = subint0->flags & SUBINT_CONFIG_L2;
}
@@ -619,6 +627,9 @@ ethernet_input_inline (vlib_main_t * vm,
}
else
{
+ if (!ethernet_address_cast (e0->dst_address) &&
+ !eth_mac_equal ((u8 *) e0, hi->hw_address))
+ error0 = ETHERNET_ERROR_L3_MAC_MISMATCH;
determine_next_node (em, variant, 0, type0, b0,
&error0, &next0);
vlib_buffer_advance (b0, sizeof (ethernet_header_t));
@@ -705,10 +716,10 @@ ethernet_input_inline (vlib_main_t * vm,
determine_next_node (em, variant, is_l20, type0, b0, &error0,
&next0);
+ ship_it0:
b0->error = error_node->errors[error0];
// verify speculative enqueue
- ship_it0:
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
to_next, n_left_to_next,
bi0, next0);
iteral.Number.Integer.Long */ }
/*
 * Copyright (c) 2019 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.
 */

#include "ATSConnector.h"

#include <hicn/transport/core/prefix.h>
#include <hicn/transport/interfaces/publication_options.h>
#include <hicn/transport/interfaces/socket_producer.h>
#include <hicn/transport/utils/spinlock.h>

#include <cassert>
#include <cstring>
#include <queue>
#include <utility>

namespace transport {

class AsyncConsumerProducer {
  using SegmentProductionPair = std::pair<uint32_t, bool>;
  using ResponseInfoMap = std::unordered_map<core::Name, SegmentProductionPair>;
  using RequestQueue = std::queue<interface::PublicationOptions>;

 public:
  explicit AsyncConsumerProducer(const std::string& prefix,
                                 std::string& ip_address, std::string& port,
                                 std::string& cache_size, std::string& mtu,
                                 std::string& first_ipv6_word);

  void start();

  void run();

 private:
  void doSend();

  void doReceive();

  void publishContent(const uint8_t* data, std::size_t size,
                      bool is_last = true, bool headers = false);

  void manageIncomingInterest(core::Name& name, core::Packet::MemBufPtr& packet,
                              utils::MemBuf* payload);

  core::Prefix prefix_;
  asio::io_service io_service_;
  interface::ProducerSocket producer_socket_;

  std::string ip_address_;
  std::string port_;
  uint32_t cache_size_;
  uint32_t mtu_;

  uint64_t request_counter_;
  asio::signal_set signals_;

  // std::unordered_map<core::Name, std::shared_ptr<ATSConnector>>
  // connection_map_;
  ATSConnector connector_;

  // ResponseInfoMap --> max_seq_number + bool indicating whether request is in
  // production
  ResponseInfoMap chunk_number_map_;
  RequestQueue response_name_queue_;
};

}  // namespace transport