gbp: enforce same endpoint mac and ip src 23/20323/3
authorBenoît Ganne <bganne@cisco.com>
Thu, 6 Jun 2019 15:53:21 +0000 (17:53 +0200)
committerNeale Ranns <nranns@cisco.com>
Wed, 26 Jun 2019 11:37:24 +0000 (11:37 +0000)
During packet classification, make sure packets coming from an EP also
matches this specific EP IP address and vice-versa. This prevents and EP
to send a packet on behalf of another EP.

Type: fix

Change-Id: I30287644ec73b90d9b6913952a82b2baedf6a5ff
Signed-off-by: Benoît Ganne <bganne@cisco.com>
src/plugins/gbp/gbp_classify_node.c
test/test_gbp.py

index a2d6d4c..9ad2b06 100644 (file)
@@ -359,12 +359,12 @@ gbp_lpm_classify_inline (vlib_main_t * vm,
       while (n_left_from > 0 && n_left_to_next > 0)
        {
          u32 bi0, sw_if_index0, fib_index0, lbi0;
+         const gbp_endpoint_t *ge0, *ge_lpm0;
          gbp_lpm_classify_next_t next0;
          const ethernet_header_t *eh0;
          const gbp_policy_dpo_t *gpd0;
          const ip4_address_t *ip4_0;
          const ip6_address_t *ip6_0;
-         const gbp_endpoint_t *ge0;
          const gbp_recirc_t *gr0;
          const dpo_id_t *dpo0;
          load_balance_t *lb0;
@@ -437,15 +437,15 @@ gbp_lpm_classify_inline (vlib_main_t * vm,
 
              if (ip4_0)
                {
-                 ge0 = gbp_endpoint_find_ip4 (ip4_0, fib_index0);
+                 ge_lpm0 = gbp_endpoint_find_ip4 (ip4_0, fib_index0);
                }
              else if (ip6_0)
                {
-                 ge0 = gbp_endpoint_find_ip6 (ip6_0, fib_index0);
+                 ge_lpm0 = gbp_endpoint_find_ip6 (ip6_0, fib_index0);
                }
              else
                {
-                 ge0 = NULL;
+                 ge_lpm0 = NULL;
                }
 
              next0 = vnet_l2_feature_next
@@ -456,9 +456,18 @@ gbp_lpm_classify_inline (vlib_main_t * vm,
               * if we found the EP by IP lookup, it must be from the EP
               * not a network behind it
               */
-             if (NULL != ge0)
+             if (NULL != ge_lpm0)
                {
-                 sclass0 = ge0->ge_fwd.gef_sclass;
+                 if (PREDICT_FALSE (ge0 != ge_lpm0))
+                   {
+                     /* an EP spoofing another EP */
+                     sclass0 = SCLASS_INVALID;
+                     next0 = GPB_LPM_CLASSIFY_DROP;
+                   }
+                 else
+                   {
+                     sclass0 = ge0->ge_fwd.gef_sclass;
+                   }
                  goto trace;
                }
            }
index cc26238..ac0fb22 100644 (file)
@@ -3617,6 +3617,16 @@ class TestGBP(VppTestCase):
                              mac=None)
         rep.add_vpp_config()
 
+        #
+        # EP1 impersonating EP3 is dropped
+        #
+        p = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
+             Dot1Q(vlan=100) /
+             ARP(op="who-has",
+             psrc="10.0.0.3", pdst="10.0.0.128",
+             hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
+        self.send_and_assert_no_replies(self.pg0, p)
+
         #
         # ARP packet from External EPs are accepted and replied to
         #
@@ -3630,11 +3640,11 @@ class TestGBP(VppTestCase):
         #
         # ARP packet from host in remote subnet are accepted and replied to
         #
-        p_arp = (Ether(src=vlan_102.remote_mac, dst="ff:ff:ff:ff:ff:ff") /
+        p_arp = (Ether(src=eep3.mac, dst="ff:ff:ff:ff:ff:ff") /
                  Dot1Q(vlan=102) /
                  ARP(op="who-has",
-                     psrc="10.0.0.17", pdst="10.0.0.128",
-                     hwsrc=vlan_102.remote_mac, hwdst="ff:ff:ff:ff:ff:ff"))
+                     psrc=eep3.ip4.address, pdst="10.0.0.128",
+                     hwsrc=eep3.mac, hwdst="ff:ff:ff:ff:ff:ff"))
         rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
 
         #