gbp: Add support for allow sclass/dclass 1 35/18935/2
authorMohsin Kazmi <sykazmi@cisco.com>
Tue, 16 Apr 2019 13:15:07 +0000 (15:15 +0200)
committerNeale Ranns <nranns@cisco.com>
Tue, 16 Apr 2019 20:08:33 +0000 (20:08 +0000)
Change-Id: I51f61a399e3eace93011f9431cbd7968e9be627c
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
src/plugins/gbp/gbp_contract.h
src/plugins/gbp/gbp_policy_dpo.c
src/plugins/gbp/gbp_policy_node.c
test/test_gbp.py

index c6e9721..9de52eb 100644 (file)
@@ -22,6 +22,7 @@
   _(ALLOW_NO_SCLASS,    "allow-no-sclass")                 \
   _(ALLOW_INTRA,        "allow-intra-sclass")              \
   _(ALLOW_A_BIT,        "allow-a-bit-set")                 \
+  _(ALLOW_SCLASS_1,     "allow-sclass-1")                  \
   _(ALLOW_CONTRACT,     "allow-contract")                  \
   _(DROP_CONTRACT,      "drop-contract")                   \
   _(DROP_ETHER_TYPE,    "drop-ether-type")                 \
index a6194df..a707789 100644 (file)
@@ -270,12 +270,12 @@ gbp_policy_dpo_inline (vlib_main_t * vm,
 {
   gbp_main_t *gm = &gbp_main;
   u32 n_left_from, next_index, *from, *to_next, thread_index;
-  u32 n_allow_intra, n_allow_a_bit;
+  u32 n_allow_intra, n_allow_a_bit, n_allow_sclass_1;
   gbp_rule_t *gu;
 
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
-  n_allow_intra = n_allow_a_bit = 0;
+  n_allow_intra = n_allow_a_bit = n_allow_sclass_1 = 0;
   thread_index = vm->thread_index;
 
   next_index = node->cached_next_index;
@@ -343,6 +343,16 @@ gbp_policy_dpo_inline (vlib_main_t * vm,
                  n_allow_intra++;
                  action0 = 0;
                }
+             else if (PREDICT_FALSE (key0.gck_src == 1 || key0.gck_dst == 1))
+               {
+                 /*
+                  * sclass or dclass 1 allowed
+                  */
+                 next0 = gpd0->gpd_dpo.dpoi_next_node;
+                 vnet_buffer2 (b0)->gbp.flags |= VXLAN_GBP_GPFLAGS_A;
+                 n_allow_sclass_1++;
+                 action0 = 0;
+               }
              else
                {
                  gci0 = gbp_contract_find (&key0);
@@ -449,7 +459,9 @@ gbp_policy_dpo_inline (vlib_main_t * vm,
   vlib_node_increment_counter (vm, node->node_index,
                               GBP_POLICY_DPO_ERROR_ALLOW_A_BIT,
                               n_allow_a_bit);
-
+  vlib_node_increment_counter (vm, node->node_index,
+                              GBP_POLICY_DPO_ERROR_ALLOW_SCLASS_1,
+                              n_allow_sclass_1);
   return from_frame->n_vectors;
 }
 
index 8fe1d7f..2cffc79 100644 (file)
@@ -116,13 +116,13 @@ gbp_policy_inline (vlib_main_t * vm,
   gbp_policy_main_t *gpm = &gbp_policy_main;
   u32 n_left_from, *from, *to_next;
   u32 next_index, thread_index;
-  u32 n_allow_intra, n_allow_a_bit;
+  u32 n_allow_intra, n_allow_a_bit, n_allow_sclass_1;
 
   next_index = 0;
   n_left_from = frame->n_vectors;
   from = vlib_frame_vector_args (frame);
   thread_index = vm->thread_index;
-  n_allow_intra = n_allow_a_bit = 0;
+  n_allow_intra = n_allow_a_bit = n_allow_sclass_1 = 0;
 
   while (n_left_from > 0)
     {
@@ -216,6 +216,21 @@ gbp_policy_inline (vlib_main_t * vm,
                  vnet_buffer2 (b0)->gbp.flags |= VXLAN_GBP_GPFLAGS_A;
                  n_allow_intra++;
                }
+             else if (PREDICT_FALSE (key0.gck_src == 1 || key0.gck_dst == 1))
+               {
+                 /*
+                  * sclass or dclass 1 allowed
+                  */
+                 next0 =
+                   vnet_l2_feature_next (b0,
+                                         gpm->l2_output_feat_next
+                                         [is_port_based],
+                                         (is_port_based ?
+                                          L2OUTPUT_FEAT_GBP_POLICY_PORT :
+                                          L2OUTPUT_FEAT_GBP_POLICY_MAC));
+                 vnet_buffer2 (b0)->gbp.flags |= VXLAN_GBP_GPFLAGS_A;
+                 n_allow_sclass_1++;
+               }
              else
                {
                  gci0 = gbp_contract_find (&key0);
@@ -377,6 +392,9 @@ gbp_policy_inline (vlib_main_t * vm,
                               GBP_POLICY_ERROR_ALLOW_INTRA, n_allow_intra);
   vlib_node_increment_counter (vm, node->node_index,
                               GBP_POLICY_ERROR_ALLOW_A_BIT, n_allow_a_bit);
+  vlib_node_increment_counter (vm, node->node_index,
+                              GBP_POLICY_ERROR_ALLOW_SCLASS_1,
+                              n_allow_sclass_1);
 
   return frame->n_vectors;
 }
index 73acfdf..44a9b39 100644 (file)
@@ -1813,6 +1813,30 @@ class TestGBP(VppTestCase):
                                               vx_tun_l2_1.sw_if_index,
                                               mac=l['mac']))
 
+        #
+        # repeat in the other EPG
+        # there's no contract between 220 and 330, but the sclass is set to 1
+        # so the packet is cleared for delivery
+        #
+        for l in learnt:
+            # a packet with an sclass from a known EPG
+            p = (Ether(src=self.pg2.remote_mac,
+                       dst=self.pg2.local_mac) /
+                 IP(src=self.pg2.remote_hosts[1].ip4,
+                    dst=self.pg2.local_ip4) /
+                 UDP(sport=1234, dport=48879) /
+                 VXLAN(vni=99, gpid=1, flags=0x88) /
+                 Ether(src=l['mac'], dst=ep.mac) /
+                 IP(src=l['ip'], dst=ep.ip4.address) /
+                 UDP(sport=1234, dport=1234) /
+                 Raw('\xa5' * 100))
+
+            rx = self.send_and_expect(self.pg2, p*65, self.pg0)
+
+            self.assertTrue(find_gbp_endpoint(self,
+                                              vx_tun_l2_1.sw_if_index,
+                                              mac=l['mac']))
+
         #
         # static EP cannot reach the learnt EPs since there is no contract
         # only test 1 EP as the others could timeout
@@ -3665,6 +3689,22 @@ class TestGBP(VppTestCase):
             self.assertEqual(inner[IP].src, "10.220.0.1")
             self.assertEqual(inner[IP].dst, "10.222.0.1")
 
+        #
+        # ping from host in remote to local external subnets
+        # there's no contract for this, but sclass is 1.
+        #
+        p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
+             IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
+             UDP(sport=1234, dport=48879) /
+             VXLAN(vni=445, gpid=1, flags=0x88) /
+             Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
+             IP(src="10.222.0.1", dst="10.220.0.1") /
+             UDP(sport=1234, dport=1234) /
+             Raw('\xa5' * 100))
+
+        rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
+        self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
+
         #
         # ping from host in remote to local external subnets
         # there's no contract for this, but the A bit is set.